Python对象持久性
我正在寻求有关在Python中实现对象持久性的方法的建议。更准确地说,我希望能够将Python对象链接到文件,这样任何打开该文件表示的Python进程都可以共享相同的信息,任何进程都可以更改其对象,并且更改将传播到其他进程,即使“存储”该对象的所有进程都已关闭,该文件将保留,并可由其他进程重新打开 在我的Python发行版中,我发现了这方面的三个主要候选对象—anydbm、pickle和shelve(dbm看起来很完美,但它仅限于Unix,我使用的是Windows)。然而,它们都有缺陷:Python对象持久性,python,persistence,Python,Persistence,我正在寻求有关在Python中实现对象持久性的方法的建议。更准确地说,我希望能够将Python对象链接到文件,这样任何打开该文件表示的Python进程都可以共享相同的信息,任何进程都可以更改其对象,并且更改将传播到其他进程,即使“存储”该对象的所有进程都已关闭,该文件将保留,并可由其他进程重新打开 在我的Python发行版中,我发现了这方面的三个主要候选对象—anydbm、pickle和shelve(dbm看起来很完美,但它仅限于Unix,我使用的是Windows)。然而,它们都有缺陷: an
- anydbm只能处理一个字符串值字典(我正在寻找一个字典列表,所有字典都有字符串键和字符串值,尽管理想情况下我会寻找一个没有类型限制的模块)
- 搁置要求在更改传播之前重新打开文件-例如,如果两个进程a和B加载同一个文件(包含搁置的空列表),并且a向列表中添加一项并调用sync(),则B在重新加载文件之前仍会将列表视为空
- pickle(我当前用于测试实现的模块)与shelve具有相同的“重新加载要求”,并且也不会覆盖以前的数据-如果进程A将15个空字符串转储到一个文件中,然后字符串“hello”,那么进程B必须加载该文件16次才能获得“hello”字符串。我目前正在处理这个问题,通过在任何写入操作之前重复读取直到文件结束(“在写入之前将板岩擦干净”),并使每个读取操作重复到文件结束,但我觉得必须有更好的方法
- Python对象的透明持久性 ZODB在下面使用pickle,所以任何可以pickle的东西都可以存储在ZODB对象存储中
- 与ACID完全兼容的事务支持(包括保存点) 这意味着,当一个进程的更改良好且准备就绪时,这些更改会传播到所有其他进程,并且每个进程在整个事务中都具有一致的数据视图
同样可以通过将ZODB数据存储在关系数据库(如PostgreSQL、MySQL或Oracle)中来实现。对于初学者,您可以将搁置数据库移植到ZODB数据库,如下所示:
#!/usr/bin/env python
import shelve
import ZODB, ZODB.FileStorage
import transaction
from optparse import OptionParser
import os
import sys
import re
reload(sys)
sys.setdefaultencoding("utf-8")
parser = OptionParser()
parser.add_option("-o", "--output", dest = "out_file", default = False, help ="original shelve database filename")
parser.add_option("-i", "--input", dest = "in_file", default = False, help ="new zodb database filename")
parser.set_defaults()
options, args = parser.parse_args()
if options.in_file == False or options.out_file == False :
print "Need input and output database filenames"
exit(1)
db = shelve.open(options.in_file, writeback=True)
zstorage = ZODB.FileStorage.FileStorage(options.out_file)
zdb = ZODB.DB(zstorage)
zconnection = zdb.open()
newdb = zconnection.root()
for key, value in db.iteritems() :
print "Copying key: " + str(key)
newdb[key] = value
transaction.commit()
我建议使用TinyDB,它更好,使用更简单
看看
mongo db
。它没有像上面的例子那样完全集成到语言中,但它将为您提供一个比对文件系统进行酸洗和在锁方面更健壮、更宽容的数据库。ZODB听起来正是我想要的(RelStorage听起来像是未来有趣的东西)-谢谢!我会测试它,如果它对我有效,我会把它标记为已回答。这听起来也是我想要的;在架子上提供什么。
#!/usr/bin/env python
import shelve
import ZODB, ZODB.FileStorage
import transaction
from optparse import OptionParser
import os
import sys
import re
reload(sys)
sys.setdefaultencoding("utf-8")
parser = OptionParser()
parser.add_option("-o", "--output", dest = "out_file", default = False, help ="original shelve database filename")
parser.add_option("-i", "--input", dest = "in_file", default = False, help ="new zodb database filename")
parser.set_defaults()
options, args = parser.parse_args()
if options.in_file == False or options.out_file == False :
print "Need input and output database filenames"
exit(1)
db = shelve.open(options.in_file, writeback=True)
zstorage = ZODB.FileStorage.FileStorage(options.out_file)
zdb = ZODB.DB(zstorage)
zconnection = zdb.open()
newdb = zconnection.root()
for key, value in db.iteritems() :
print "Copying key: " + str(key)
newdb[key] = value
transaction.commit()