Python Data Persistence 简明教程

Data Persistence - ZODB

ZODB ( Zope object Database ) 是一个用于存储 Python 对象的数据库。它是 ACID 兼容的——在 NOSQL 数据库中找不到此特性。ZODB 也是开源的,像许多 NoSQL 数据库一样,横向可伸缩且无模式。然而,它不分布式,也没有提供简单的复制。它为 Python 对象提供了持久性机制。它属于 Zope 应用程序服务器的一部分,但也可以独立使用。

ZODB 由 Zope Corporation 的 Jim Fulton 创建。它最初只是一个简单的持久对象系统。其当前版本是 5.5.0,是用 Python 完全编写的,使用 Python 内置对象持久性(pickle)的扩展版本。

ZODB 的一些主要特性包括:

  1. transactions

  2. history/undo

  3. transparently pluggable storage

  4. built-in caching

  5. multiversion concurrency control (MVCC)

  6. scalability across a network

ZODB 是一个 hierarchical 数据库。有一个根对象,在创建数据库时初始化。根对象像 Python 字典一样使用,它可以包含其他对象(这些对象本身也可以像字典)。将一个对象存储在数据库中,只需将其分配给容器中一个新的键即可。

ZODB 对于数据分层并且可能存在比写入更多的读取的应用程序很有用。ZODB 是 pickle 对象的拓展。这就是为什么它只能通过 Python 脚本处理。

要安装 ZODB 的最新版本,我们可以使用 pip 实用程序:

pip install zodb

以下依赖项也将被安装:

  1. BTrees==4.6.1

  2. cffi==1.13.2

  3. persistent==4.5.1

  4. pycparser==2.19

  5. six==1.13.0

  6. transaction==2.4.0

ZODB 提供以下存储选项:

FileStorage

这是默认值。所有内容存储在一个大型 Data.fs 文件中,它本质上是一个事务日志。

DirectoryStorage

这为每个对象修订版存储一个文件。在这种情况下,它不需要在非正常关闭时重建 Data.fs.index。

RelStorage

这将 pickle 存储在关系数据库中。PostgreSQL、MySQL 和 Oracle 均受支持。

要创建 ZODB 数据库,我们需要一个存储、一个数据库和最终一个连接。

第一步是拥有一个存储对象。

import ZODB, ZODB.FileStorage
storage = ZODB.FileStorage.FileStorage('mydata.fs')

DB 类使用这个存储对象获取数据库对象。

db = ZODB.DB(storage)

向 DB 构造函数传递 None 创建一个内存数据库。

Db=ZODB.DB(None)

最后,我们与数据库建立连接。

conn=db.open()

然后,连接对象允许你通过“root()”方法访问数据库的“根”。“根”对象是保存所有持久性对象的字典。

root = conn.root()

例如,我们这样向根对象添加一个学生列表:

root['students'] = ['Mary', 'Maya', 'Meet']

更改没有持久性储存到数据库中,直至我们提交交易。

import transaction
transaction.commit()

要储存对象的用户定义类,该类必须继承自持久性父类的 Persistent。

Advantages of Subclassing

Persistent 类的子类的优点如下:

  1. 数据库将自动通过设置属性跟踪对象更改。

  2. 将数据保存在自己的数据库记录中。

  3. 你可以保存未对 Persistent 进行子类化的数据,但它将存储在属于引用的任何持久对象的数据库记录中。非持久对象是它们的包含持久对象拥有的,并且如果多个持久对象引用了相同的非持久子对象,它们将获取自己的副本。

这里使用将 Student 类定义为 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() 事务控制。