在Python中的Sqlite3中将元组保存为blob数据类型

时间:2011-03-10 13:12:50

标签: python database sqlite

我在python中有一本字典。它们的键是具有不同大小的元组,包含unicode字符,值只是一个int数。我想将这个字典插入带有2列表的sqlite数据库中。

第一列用于键值,第二列应具有相应的int值。我为什么要这样做?好吧,我有一个非常大的字典,我使用cPickle,甚至将协议设置为2.大小仍然很大,保存和加载此文件需要很多时间。所以我决定把它保存在db中。该字典仅在程序开头加载一次到内存中,因此没有额外的操作。

现在的问题是我想将元组完全保存为元组(而不是字符串),所以每当我将表加载到内存中时,我都可以立即构建我的字典而没有任何问题。 有谁知道我怎么能这样做?

3 个答案:

答案 0 :(得分:3)

有几件事。首先,SQLite不允许您直接存储Python数据结构。其次,我猜你想要能够根据需要通过元组键查询值,所以你不想腌制和取消选择,然后搜索字典中的键。

问题是,你不能用元组查询,你不能将元组条目分成它们自己的列,因为它们的大小各不相同。如果必须使用SQLite,则几乎必须连接元组中的unicode字符,可能使用的分隔符不是元组值中的1个字符。将其用作键,并将其存储在SQLite中作为主键列的列中。

def tuple2key(t, delimiter=u':'):
    return delimiter.join(t)

import sqlite3

conn = sqlite3.connect('/path/to/your/db')
cur = conn.cursor()

cur.execute('''create table tab (k text primary key, value integer)''')

# store the dict into a table
for k, v in my_dict.iteritems():
    cur.execute('''insert into tab values (?, ?)''', (tuple2key(k), v))

cur.commit()

# query the values
v = cur.execute(''' select value from tab where key = ? ''', tuple2key((u'a',u'b'))).fetchone()

答案 1 :(得分:2)

可以将元组存储到sqlite db中并在元组上创建索引。它需要一些额外的代码来完成它。 在这种特殊情况下将元组存储到db中是否是一个合适的解决方案是另一个问题(可能是一个双键解决方案更适合)。

import sqlite3
import pickle

def adapt_tuple(tuple):
    return pickle.dumps(tuple)    

sqlite3.register_adapter(tuple, adapt_tuple)    #cannot use pickle.dumps directly because of inadequate argument signature 
sqlite3.register_converter("tuple", pickle.loads)

def collate_tuple(string1, string2):
    return cmp(pickle.loads(string1), pickle.loads(string2))

con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)

con.create_collation("cmptuple", collate_tuple)

cur = con.cursor()
cur.execute("create table test(p tuple unique collate cmptuple) ")
cur.execute("create index tuple_collated_index on test(p collate cmptuple)")

#insert
p = (1,2,3)
p1 = (1,2)

cur.execute("insert into test(p) values (?)", (p,))
cur.execute("insert into test(p) values (?)", (p1,))

#ordered select
cur.execute("select p from test order by p collate cmptuple")

答案 2 :(得分:-1)

我认为最好在表中创建3列 - key1,key2和value。

如果您希望将密钥保存为元组,您仍然可以使用pickle但仅适用于密钥。然后你可以把它保存为blob。

>>> pickle.dumps((u"\u20AC",u"\u20AC"))
'(V\\u20ac\np0\ng0\ntp1\n.'
>>> pickle.loads(_)
(u'\u20ac', u'\u20ac')
>>>