将python中的列表作为二进制数据(即BLOB单元格)转储到sqlite3数据库中的最优雅方法是什么?
data = [ 0, 1, 2, 3, 4, 5 ]
# now write this to db as binary data
# 0000 0000
# 0000 0001
# ...
# 0000 0101
答案 0 :(得分:19)
看起来Brian的解决方案符合您的需求,但请记住,使用该方法只需将数据存储为字符串。
如果要将原始二进制数据存储到数据库中(因此它不会占用太多空间),请将数据转换为二进制 sqlite对象,然后将其添加到数据库中
query = u'''insert into testtable VALUES(?)'''
b = sqlite3.Binary(some_binarydata)
cur.execute(query,(b,))
con.commit()
(由于某些原因,这似乎没有在python文档中记录)
以下是有关sqlite BLOB数据限制的一些注意事项:
答案 1 :(得分:8)
假设您希望将其视为8位无符号值序列,请使用array
模块。
a = array.array('B', data)
>>> a.tostring()
'\x00\x01\x02\x03\x04\x05'
如果要将数据视为不同类型,请使用与'B'
不同的类型代码。例如。 'b'表示有符号字节序列,或'i'
表示有符号整数。
答案 2 :(得分:3)
我有同样的问题,我正在考虑以另一种方式解决这个问题。
我认为pickle模块完全是为了这样的事情(在python对象上进行序列化)
示例(这个用于转储到文件...但我认为它很容易改变数据库存储)
保存:
# Save a dictionary into a pickle file.
import pickle
favorite_color = { "lion": "yellow", "kitty": "red" }
pickle.dump( favorite_color, open( "save.p", "w" ) )
装载:
# Load the dictionary back from the pickle file.
import pickle
favorite_color = pickle.load( open( "save.p" ) )
恕我直言,我认为这种方式更优雅,更安全(适用于任何python对象)。
那是我的2美分
更新: After doing a bit of search on my idea,他们在我的解决方案上显示了一些问题(我不能在该字段上进行sql搜索)。但我仍然认为这是一个不错的解决方案(如果你不需要搜索那个领域。
答案 3 :(得分:2)
在SourceForge上查看这个通用解决方案,它涵盖了任意Python对象(包括列表,元组,字典等):
y_serial.py module ::使用SQLite的仓库Python对象
“序列化+持久性::在几行代码中,将Python对象压缩并注释为SQLite;然后通过关键字按时间顺序检索它们,而不使用任何SQL。最有用的”标准“模块,用于存储无模式数据的数据库。“
答案 4 :(得分:1)
可以将对象数据存储为pickle dump,jason等,但也可以对它们进行索引,限制它们并运行使用这些索引的选择查询。以下是元组的示例,可以轻松应用于任何其他python类。所有需要的都在python sqlite3文档中解释(有人已发布链接)。无论如何,在以下示例中将它们全部放在一起:
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))
#########################
# 1) Using declared types
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)")
cur.execute("select name, type from sqlite_master") # where type = 'table'")
print(cur.fetchall())
p = (1,2,3)
p1 = (1,2)
cur.execute("insert into test(p) values (?)", (p,))
cur.execute("insert into test(p) values (?)", (p1,))
cur.execute("insert into test(p) values (?)", ((10, 1),))
cur.execute("insert into test(p) values (?)", (tuple((9, 33)) ,))
cur.execute("insert into test(p) values (?)", (((9, 5), 33) ,))
try:
cur.execute("insert into test(p) values (?)", (tuple((9, 33)) ,))
except Exception as e:
print e
cur.execute("select p from test order by p")
print "\nwith declared types and default collate on column:"
for raw in cur:
print raw
cur.execute("select p from test order by p collate cmptuple")
print "\nwith declared types collate:"
for raw in cur:
print raw
con.create_function('pycmp', 2, cmp)
print "\nselect grater than using cmp function:"
cur.execute("select p from test where pycmp(p,?) >= 0", ((10, ),) )
for raw in cur:
print raw
cur.execute("select p from test where pycmp(p,?) >= 0", ((3,)))
for raw in cur:
print raw
print "\nselect grater than using collate:"
cur.execute("select p from test where p > ?", ((10,),) )
for raw in cur:
print raw
cur.execute("explain query plan select p from test where p > ?", ((3,)))
for raw in cur:
print raw
cur.close()
con.close()