存储相对于基本存储的更改的zodb存储
zc.demostorage2的Python项目详细描述
demoStorage2模块提供了一个存储实现 包装两个存储,一个基本存储和一个存储以保存更改。 基本存储从未写入。所有新记录都写入 更改存储。两个存储都应:
- 使用压缩的64位无符号整数作为对象ID,
- 按顺序分配对象ID,从0开始,然后
- 在更改存储的情况下,接受外部分配的对象ID。
此外,假设 在第一个存储器中分配
注意,DemoStorage还假设它的基本存储使用64位 按顺序分配的无符号整数对象ID。
Configuration
下面的部分演示如何从 Python。如果使用ZConfig,则需要:
- 导入zc.demostorage2
- 包括演示2部分
下面的示例演示如何配置演示存储以及如何 使用python中的配置:
>>> import ZODB.config >>> storage = ZODB.config.storageFromString(""" ... ... %import zc.demostorage2 ... ... <demostorage2> ... <filestorage base> ... path base.fs ... </filestorage> ... <filestorage changes> ... path changes.fs ... </filestorage> ... </demostorage2> ... """)
这将创建一个从文件存储获取基本数据的演示存储 命名为base.fs并将更改存储在名为changes.fs的文件存储中。
>>> storage <DemoStorage2: DemoStorage2(base.fs, changes.fs)>>>> storage.close()
Demo (doctest)
请注意,大多数人将通过zconfig配置存储。如果 你就是那种人,你可能想停在这里:)的 下面的示例向您展示了如何使用python中的存储,但是 同时练习很多你可能不感兴趣的细节。
为了了解这是如何工作的,我们将从创建基本存储和 将对象(除根对象外)放入其中:
>>> from ZODB.FileStorage import FileStorage >>> base = FileStorage('base.fs') >>> from ZODB.DB import DB >>> db = DB(base) >>> from persistent.mapping import PersistentMapping >>> conn = db.open() >>> conn.root()['1'] = PersistentMapping({'a': 1, 'b':2}) >>> import transaction >>> transaction.commit() >>> db.close() >>> import os >>> original_size = os.path.getsize('base.fs')
现在,让我们以只读模式重新打开基本存储:
>>> base = FileStorage('base.fs', read_only=True)
并打开一个新存储以存储更改:
>>> changes = FileStorage('changes.fs')
在demofilestorage中组合2:
>>> from zc.demostorage2 import DemoStorage2 >>> storage = DemoStorage2(base, changes)
如果没有事务,存储将报告上一个事务 基本数据库的:
>>> storage.lastTransaction() == base.lastTransaction() True
让我们添加一些数据:
>>> db = DB(storage) >>> conn = db.open() >>> items = conn.root()['1'].items() >>> items.sort() >>> items [('a', 1), ('b', 2)]>>> conn.root()['2'] = PersistentMapping({'a': 3, 'b':4}) >>> transaction.commit()>>> conn.root()['2']['c'] = 5 >>> transaction.commit()
这里我们可以看到,我们没有修改基本存储:
>>> original_size == os.path.getsize('base.fs') True
但我们已经修改了更改数据库:
>>> len(changes) 2
我们的lastTransaction反映了更改的lastTransaction:
>>> storage.lastTransaction() > base.lastTransaction() True>>> storage.lastTransaction() == changes.lastTransaction() True
让我们来看看其中的一些方法,这样我们就可以看到如何委派 新的存储空间:
>>> from ZODB.utils import p64, u64 >>> storage.load(p64(0), '') == changes.load(p64(0), '') True >>> storage.load(p64(0), '') == base.load(p64(0), '') False >>> storage.load(p64(1), '') == base.load(p64(1), '') True>>> serial = base.getTid(p64(0)) >>> storage.loadSerial(p64(0), serial) == base.loadSerial(p64(0), serial) True>>> serial = changes.getTid(p64(0)) >>> storage.loadSerial(p64(0), serial) == changes.loadSerial(p64(0), ... serial) True
新对象的对象ID相当大:
>>> u64(conn.root()['2']._p_oid) 4611686018427387905L
让我们看看其他一些方法:
>>> storage.getName() 'DemoStorage2(base.fs, changes.fs)'>>> storage.sortKey() == changes.sortKey() True>>> storage.getSize() == changes.getSize() True>>> len(storage) == len(changes) True
撤消方法只需从更改存储中复制即可:
>>> [getattr(storage, name) == getattr(changes, name) ... for name in ('supportsUndo', 'undo', 'undoLog', 'undoInfo') ... ] [True, True, True, True]