2011-03-10 115 views
0

我在Python中有一個字典。它們的鍵是包含unicode字符的不同大小的元組,並且這些值只是一個int數。我想插入這個字典到SQLite數據庫與2列表。將Tuple保存爲Python中的Sqlite3中的blob數據類型

第一列是鍵值,第二列應該有相應的int值。我爲什麼要這樣做?以及我有一個非常大的字典,我用cPickle,甚至將協議設置爲2.尺寸仍然很大,保存和加載這個文件需要很多時間。所以我決定把它保存在db中。這個字典在程序開始時只加載一次內存,所以沒有額外的操作。

現在的問題是我想將元組完全保存爲元組(不是字符串),所以無論何時我將表加載到內存中,我都可以立即構建我的字典而不會出現問題。 有誰知道我該怎麼做?

回答

3

一些事情。首先,SQLite不允許你直接存儲Python數據結構。其次,我猜你希望能夠根據需求通過元組鍵來查詢值,所以你不想醃菜和不點菜,然後搜索字典中的鍵。

問題是,您無法使用元組進行查詢,也無法將元組條目拆分到自己的列中,因爲它們大小各不相同。如果您必須使用SQLite,則幾乎必須連接元組中的unicode字符,可能使用不是元組值中的字符之一的分隔符。將其用作鍵,並將其作爲主鍵列存儲到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

我認爲最好在表格中創建3列 - key1,key2和value。

如果您希望將密鑰保存爲元組,您仍然可以使用pickle,但僅適用於密鑰。然後你可以將它保存爲blob。

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

可以將元組存儲到sqlite數據庫中,並在元組上創建索引。它需要一些額外的代碼才能完成。 在這種特殊情況下,將元組存儲到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") 
相關問題