我应该知道的任何陷阱?我可以将它存储在文本字段中,还是需要使用blob?(我对pickle或sqlite都不太熟悉,所以我想确保我用一些高级设计思想咆哮着正确的树.)
我也需要达到同样的目的.
事实证明,在我最终想出来之前,这让我非常头疼,感谢这篇文章,如何让它以二进制格式工作.
pdata = cPickle.dumps(data, cPickle.HIGHEST_PROTOCOL) curr.execute("insert into table (data) values (:data)", sqlite3.Binary(pdata))
您必须指定转储的第二个参数以强制进行二进制酸洗.
另请注意sqlite3.Binary使其适合BLOB字段.
curr.execute("select data from table limit 1") for row in curr: data = cPickle.loads(str(row['data']))
当检索BLOB字段时,sqlite3获得一个'缓冲区'python类型,需要在传递给loads方法之前使用str进行strinyfied .
如果要存储pickle对象,则需要使用blob,因为它是二进制数据.但是,您可以使用base64编码pickle对象以获取可以存储在文本字段中的字符串.
但是,一般来说,做这种事情表明设计不好,因为你存储的是不透明的数据,你就失去了使用SQL对数据进行任何有用操作的能力.虽然我不知道你在做什么,但我真的无法对它进行道德呼唤.
我写了一个关于这个想法的博客,除了一个泡菜,我使用了json,因为我希望它可以与perl和其他程序互操作.
http://writeonly.wordpress.com/2008/12/05/simple-object-db-using-json-and-python-sqlite/
在架构上,这是获取任意数据结构的持久性,事务等的快速而肮脏的方法.我发现这个组合在我想要持久性时非常有用,并且不需要在sql层中用数据做很多事情(或者在sql中处理它非常复杂,而且对于生成器来说很简单).
代码本身很简单:
# register the "loader" to get the data back out. sqlite3.register_converter("pickle", cPickle.loads)
然后,当你想把它转储到数据库中时,
p_string = p.dumps( dict(a=1,b=[1,2,3])) conn.execute(''' create table snapshot( id INTEGER PRIMARY KEY AUTOINCREMENT, mydata pickle); ''') conn.execute(''' insert into snapshot values (null, ?)''', (p_string,)) ''')