我可以将 python 字典pickle到sqlite3文本字段中吗?
有什么我应该注意的问题吗? 我可以将其存储在文本字段中,还是需要使用 blob? (我对 pickle 或 sqlite 都不太熟悉,所以我想确保我用我的一些高级设计思想找到了正确的方向。)
Any gotchas I should be aware of? Can I store it in a text field, or do I need to use a blob?
(I'm not overly familiar with either pickle or sqlite, so I wanted to make sure I'm barking up the right tree with some of my high-level design ideas.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
我也需要实现同样的目标。
事实证明,在我最终弄清楚之前,它让我相当头痛, 感谢这篇文章,如何实际使其以二进制格式工作。
要插入/更新:
您必须指定转储的第二个参数以强制进行二进制酸洗。
另请注意 sqlite3.Binary 以使其适合 BLOB 字段。
检索数据:
检索 BLOB 字段时,sqlite3 获取一个“缓冲区”python 类型,在传递给 load 方法之前需要使用 str 对其进行 strinyfied。
I needed to achieve the same thing too.
I turns out it caused me quite a headache before I finally figured out, thanks to this post, how to actually make it work in a binary format.
To insert/update:
You must specify the second argument to dumps to force a binary pickling.
Also note the sqlite3.Binary to make it fit in the BLOB field.
To retrieve data:
When retrieving a BLOB field, sqlite3 gets a 'buffer' python type, that needs to be strinyfied using str before being passed to the loads method.
如果要存储 pickle 对象,则需要使用 blob,因为它是二进制数据。 但是,您可以对 pickled 对象进行 base64 编码以获得可存储在文本字段中的字符串。
不过,一般来说,这样做表明设计很糟糕,因为您存储的是不透明的数据,因此您失去了使用 SQL 对该数据进行任何有用操作的能力。 尽管不知道你实际上在做什么,但我无法真正对此做出道德呼吁。
If you want to store a pickled object, you'll need to use a blob, since it is binary data. However, you can, say, base64 encode the pickled object to get a string that can be stored in a text field.
Generally, though, doing this sort of thing is indicative of bad design, since you're storing opaque data you lose the ability to use SQL to do any useful manipulation on that data. Although without knowing what you're actually doing, I can't really make a moral call on it.
我写了一篇关于这个想法的博客,除了使用 json 代替 pickle 之外,因为我希望它能够与 perl 和其他程序互操作。
http://writeonly。 wordpress.com/2008/12/05/simple-object-db-using-json-and-python-sqlite/
从架构上来说,这是一种快速而肮脏的方式来获取任意的持久性、事务等。数据结构。 我发现当我想要持久性并且不需要在 sql 层中对数据做太多操作时(或者在 sql 中处理起来非常复杂,而在生成器中处理起来很简单),这种组合非常有用。
代码本身非常简单:
然后,当您想将其转储到数据库中时,
I wrote a blog about this idea, except instead of a pickle, I used json, since I wanted it to be interoperable with perl and other programs.
http://writeonly.wordpress.com/2008/12/05/simple-object-db-using-json-and-python-sqlite/
Architecturally, this is a quick and dirty way to get persistence, transactions, and the like for arbitrary data structures. I have found this combination to be really useful when I want persistence, and don't need to do much in the sql layer with the data (or it's very complex to deal with in sql, and simple with generators).
The code itself is pretty simple:
Then, when you want to dump it into the db,
Pickle 具有文本和二进制输出格式。 如果您使用基于文本的格式,则可以将其存储在 TEXT 字段中,但如果您使用(更有效的)二进制格式,则它必须是 BLOB。
Pickle has both text and binary output formats. If you use the text-based format you can store it in a TEXT field, but it'll have to be a BLOB if you use the (more efficient) binary format.
我必须同意这里的一些评论。 请小心并确保您确实想要将 pickle 数据保存在数据库中,可能有更好的方法。
无论如何,我过去在尝试将二进制数据保存在 sqlite 数据库中时遇到了麻烦。
显然你必须使用 sqlite3.Binary() 来为 sqlite 准备数据。
这是一些示例代码:
I have to agree with some of the comments here. Be careful and make sure you really want to save pickle data in a db, there's probably a better way.
In any case I had trouble in the past trying to save binary data in the sqlite db.
Apparently you have to use the sqlite3.Binary() to prep the data for sqlite.
Here's some sample code:
由于 Pickle 可以将对象图转储到字符串中,因此应该是可能的。
请注意,尽管 SQLite 中的 TEXT 字段使用数据库编码,因此您可能需要在取消 pickle 之前将其转换为简单的字符串。
Since Pickle can dump your object graph to a string it should be possible.
Be aware though that TEXT fields in SQLite uses database encoding so you might need to convert it to a simple string before you un-pickle.
如果字典可以被 pickle,它也可以存储在 text/blob 字段中。
只需要注意无法pickle的字典(又名包含无法pickle的对象)。
If a dictionary can be pickled, it can be stored in text/blob field as well.
Just be aware of the dictionaries that can't be pickled (aka that contain unpickable objects).
是的,您可以将 pickled 对象存储在 SQLite3 数据库的 TEXT 或 BLOB 字段中,正如其他人所解释的那样。
请注意,某些对象无法腌制。 内置的容器类型可以(dict、set、list、tuple等)。 但某些对象(例如文件句柄)引用其自身数据结构外部的状态,而其他扩展类型也有类似的问题。
由于字典可以包含任意嵌套数据结构,因此它可能无法进行pickle。
Yes, you can store a pickled object in a TEXT or BLOB field in an SQLite3 database, as others have explained.
Just be aware that some object cannot be pickled. The built-in container types can (dict, set, list, tuple, etc.). But some objects, such as file handles, refer to state that is external to their own data structures, and other extension types have similar problems.
Since a dictionary can contain arbitrary nested data structures, it might not be pickle-able.
SpoonMeiser 是正确的,您需要有充分的理由将其放入数据库。
编写使用 SQLite 实现持久性的 Python 对象并不困难。 然后您也可以使用 SQLite CLI 来处理数据。 根据我的经验,这值得额外的工作,因为许多调试和管理功能可以简单地从 CLI 执行,而不是编写特定的 Python 代码。
在项目的早期阶段,我按照您的建议进行了操作,最终为每个业务对象重写了一个 Python 类(注意:我没有说每个表!)这样应用程序的主体就可以专注于需要“做什么”而不是“如何”完成。
SpoonMeiser is correct, you need to have a strong reason to pickle into a database.
It's not difficult to write Python objects that implement persistence with SQLite. Then you can use the SQLite CLI to fiddle with the data as well. Which in my experience is worth the extra bit of work, since many debug and admin functions can be simply performed from the CLI rather than writing specific Python code.
In the early stages of a project, I did what you propose and ended up re-writing with a Python class for each business object (note: I didn't say for each table!) This way the body of the application can focus on "what" needs to be done rather than "how" it is done.
考虑到您的要求是保存一个字典,然后将其吐出来以供用户“观看乐趣”,另一种选择是使用
shelve
模块,它可以让您将任何可腌制的数据保存到文件中。 Python 文档位于此处。The other option, considering that your requirement is to save a dict and then spit it back out for the user's "viewing pleasure", is to use the
shelve
module which will let you persist any pickleable data to file. The python docs are here.根据您正在处理的内容,您可能需要查看 shove 模块。 它做了类似的事情,它在 sqlite 数据库(以及各种其他选项)中自动存储 Python 对象,并假装是一本字典(就像 搁置模块)。
Depending on what you're working on, you might want to look into the shove module. It does something similar, where it auto-stores Python objects inside a sqlite database (and all sorts of other options) and pretends to be a dictionary (just like the shelve module).
可以将对象数据存储为 pickle dump、jason 等,但也可以对它们进行索引、限制它们并运行使用这些索引的选择查询。 这是元组的示例,可以轻松应用于任何其他 python 类。 python sqlite3 文档中解释了所需的一切(有人已经发布了链接)。 无论如何,这里将所有内容放在下面的示例中:
It is possible to store object data as pickle dump, jason etc but it is also possible to index, them, restrict them and run select queries that use those indices. Here is example with tuples, that can be easily applied for any other python class. All that is needed is explained in python sqlite3 documentation (somebody already posted the link). Anyway here it is all put together in the following example:
许多应用程序使用 sqlite3 作为 SQLAlchemy 的后端,因此,自然地,这个问题也可以在 SQLAlchemy 框架中提出(这就是我遇到这个问题的方式)。
为此,需要定义需要存储泡菜数据的列来存储“PickleType”数据。 实现非常简单:(
我并不是说这个示例最适合使用 pickle,正如其他人指出的那样。)
Many applications use sqlite3 as a backend for SQLAlchemy so, naturally, this question can be asked in the SQLAlchemy framework as well (which is how I came across this question).
To do this, one will have wanted to define the column in which the pickle data is desired to be stored to store "PickleType" data. The implementation is pretty straightforward:
(I'm not claiming that this example would best be suited to use pickle, as others have noted issues with.)
请参阅 SourceForge 上的此解决方案:
y_serial.py 模块 :: 使用 SQLite 仓库 Python 对象
“序列化 + 持久化 :: 用几行代码,将 Python 对象压缩并注释到 SQLite 中;然后按时间顺序检索它们,无需任何 SQL。大多数数据库存储无模式数据的有用“标准”模块。”
http://yserial.sourceforge.net
See this solution at SourceForge:
y_serial.py module :: warehouse Python objects with SQLite
"Serialization + persistance :: in a few lines of code, compress and annotate Python objects into SQLite; then later retrieve them chronologically by keywords without any SQL. Most useful "standard" module for a database to store schema-less data."
http://yserial.sourceforge.net