数据持久性 ZODB
ZODB( Zope对象数据库 )是用于存储Python对象的数据库。它符合ACID标准–这是NOSQL数据库所没有的功能。ZODB也是开源的,水平可扩展的,无模式的,像许多NoSQL数据库。然而,它不是分布式的,不提供简单的复制。它为Python对象提供持久化机制。它是Zope应用服务器的一部分,但也可以独立使用。
ZODB是由Zope公司的Jim Fulton创建的。它开始是简单的持久化对象系统。它目前的版本是5.5.0,完全用Python编写。使用Python内置对象持久性(pickle)的扩展版本。
ZODB的一些主要特性是 −
- 交易
- 历史/undo
- 透明的可插拔存储
- 内置缓存
- 多版本并发控制(MVCC)。
- 跨网络的可扩展性
ZODB是一个 分层的 数据库。有一个根对象,在数据库被创建时被初始化。根对象的使用就像Python字典一样,它可以包含其他对象(这些对象本身可以是类似字典的)。要在数据库中存储一个对象,只需在它的容器中把它分配给一个新的键。
ZODB对于那些数据是分层的,并且可能有更多的读比写的应用是很有用的。ZODB是pickle对象的一个扩展。这就是为什么它只能通过Python脚本来处理。
要安装最新版本的ZODB,请使用pip工具 —
pip install zodb
以下依赖项也已安装
- BTrees==4.6.1
- cffi==1.13.2
- persistent==4.5.1
- pycparser==2.19
- six==1.13.0
- transaction==2.4.0
ZODB提供了以下的存储选项 –
文件存储
这是默认的。所有的东西都存储在一个大的Data.fs文件中,它本质上是一个事务日志。
目录存储
这为每个对象修订版存储一个文件。在这种情况下,它不需要在不干净的关机时重建Data.fs.索引。
关系存储(RelStorage)
这在一个关系型数据库中存储腌制物。支持PostgreSQL、MySQL和Oracle。
为了创建ZODB数据库,我们需要一个存储,一个数据库和最后一个连接。
第1步是要有存储对象。
import ZODB, ZODB.FileStorage
storage = ZODB.FileStorage.FileStorage('mydata.fs')
DB类使用这个存储对象来获得数据库对象。
db = ZODB.DB(storage)
将None传给DB构造函数以创建内存数据库。
Db=ZODB.DB(None)
最后,我们与数据库建立连接。
conn=db.open()
然后连接对象通过’root()’方法让你访问数据库的’根’。根 “对象是保存你所有持久化对象的字典。
root = conn.root()
例如,我们向根对象添加一个学生名单,如下所示
root['students'] = ['Mary', 'Maya', 'Meet']
在我们提交事务之前,这一变化不会永久地保存在数据库中。
import transaction
transaction.commit()
要存储一个用户定义的类的对象,该类必须继承自persistent.Persistent父类。
子类化的优势
子类化的Persistent类有如下优点
- 数据库将自动跟踪通过设置属性进行的对象变化。
-
数据将被保存在它自己的数据库记录中。
-
你可以保存没有子类Persistent的数据,但它将被保存在引用它的任何持久化对象的数据库记录中。非持久化对象被其包含的持久化对象所拥有,如果多个持久化对象引用同一个非持久化子对象,它们会得到自己的副本。
让我们使用定义一个学生类的子类Persistent类,如下所示
import persistent
class student(persistent.Persistent):
def __init__(self, name):
self.name = name
def __repr__(self):
return str(self.name)
为了添加这个类的对象,让我们首先按照上面的描述建立连接。
import ZODB, ZODB.FileStorage
storage = ZODB.FileStorage.FileStorage('studentdata.fs')
db = ZODB.DB(storage)
conn=db.open()
root = conn.root()
声明对象并添加到根目录,然后提交交易
s1=student("Akash")
root['s1']=s1
import transaction
transaction.commit()
conn.close()
由于根对象类似于内置的字典,所有添加到根中的对象的列表可以在items()方法的帮助下作为一个视图对象被检索。
print (root.items())
ItemsView({'s1': Akash})
从根中获取特定对象的属性。
print (root['s1'].name)
Akash
该对象可以很容易地被更新。由于ZODB API是一个纯Python包,它不需要使用任何外部的SQL类型语言。
root['s1'].name='Abhishek'
import transaction
transaction.commit()
数据库将被立即更新。请注意,事务类也定义了abort()函数,它类似于SQL中的rollback()事务控制。