Python之对象数据库ZODB
2016-09-25 15:22
375 查看
一、基本概念
关系数据库并不是Python程序员唯一可用的解决方案。通常,对象数据库可能更适合解决某些问题。ZODB是一个可扩展和冗余的对象数据库,其专注于存储可扩展的对象,而没有天生“对象-关系”不匹配情况:在尝试将面向对象的语言与关系查询系统映射对象建立关系时,可能会出现这种不匹配情况。
二、ZODB使用
建立和断开与ZODB的连接
连接到ZODB的标准方法设计创建四个对象:存储数据库数据的方法、围绕存储并未存储提供实际数据库行为“db”包装、启动与该数据库的特定会话“connection”对象、允许我们访问包含在数据库中的对象层次结构的根的“dbroot”对象。以下所有代码示例都需要将下面代码片段放在Python文件中的示例代码前面,以便正确地打开和关闭ZODB示例:
使用ZODB
存储简单Python数据
ZODB数据库可以存储所有类型的Python对象。
存储简单Python数据
获取简单数据
注意:我们使用文件名"Data.fs"纯粹是为了遵循传统,因为许多ZODB安装在使用特定文件名方面实际上已经实现了标准化,你可以随心所欲地使用任何名称。
更改简单数据
当将某个键设置为新值,ZODB始终能够了解这一点。因此,对上面的数据库进行类型如下的更改将会自动别检测和持久化:
如果打算更改——而不是完全替换——类似如此的复杂对象,需要设置数据库根的属性 _p_changed,以通知它需要重新存储其下的属性:
删除对象:
注意:如果没有调用transaction.commit(),则上面更改都不会对数据库产生任何影响。正如在关系数据库中一样,只有通过提交已执行的操作,这些操作才会出现在数据库里。
持久化对象
当然,很少有Python程序员希望使用上面的诸如列表、元祖和字典等日益复杂的数据结构。相反,希望创建全能的Python对象,并且其属性将会自动地持久化。下面介绍如何定义一个可持久到数据库的类型。为此,该类将必须从Persistent继承。
存储对象
现在可以创建该类的几个实例,并在ZODB中将其持久化:
获取对象
正如“dhroot”对象能够自动检测在其键索引处放置的值一样,持久化对象将在您设置其属性时,自动执行检测,并将属性保存到数据库。
但是,如果您在某个对象下面存储复杂数据类型,则会出现与连接到数据根的复杂数据类型完全相同的问题。必须像前面一样设置 _p_changed 属性:
最后,ZODB数据库实例很容易维护。由于ZODB数据库实例不包含需要设计或修改的模式,要执行的唯一例行维护是定期压缩以防止其耗尽整个磁盘。为了支持事务回滚,写到ZODB数据库的每个新的更改实际上都是追加到“Data.fs”文件,而不是更新该文件中已经存在的信息。要删除随着事务提交二积累的旧信息,ZODB管理员必须偶尔对其数据进行压缩。
注意:一次只有一个程序能够安全地打开“Data.fs”文件
参考地址:http://www.ibm.com/developerworks/cn/aix/library/au-zodb/
ZODB官方:http://www.zodb.org
关系数据库并不是Python程序员唯一可用的解决方案。通常,对象数据库可能更适合解决某些问题。ZODB是一个可扩展和冗余的对象数据库,其专注于存储可扩展的对象,而没有天生“对象-关系”不匹配情况:在尝试将面向对象的语言与关系查询系统映射对象建立关系时,可能会出现这种不匹配情况。
二、ZODB使用
建立和断开与ZODB的连接
连接到ZODB的标准方法设计创建四个对象:存储数据库数据的方法、围绕存储并未存储提供实际数据库行为“db”包装、启动与该数据库的特定会话“connection”对象、允许我们访问包含在数据库中的对象层次结构的根的“dbroot”对象。以下所有代码示例都需要将下面代码片段放在Python文件中的示例代码前面,以便正确地打开和关闭ZODB示例:
使用ZODB
#-*-coding: UTF-8 -*- from ZODB import FileStorage, DB import transaction class MyZODB(object): def __init__(self, path): self.storage = FileStorage.FileStorage(path) self.db = DB(self.storage) self.connection = self.db.open() self.dbroot = self.connection.root() def close(self): self.connection.close() self.db.close() self.storage.close()
存储简单Python数据
ZODB数据库可以存储所有类型的Python对象。
存储简单Python数据
from myzodb import MyZODB, transaction db = MyZODB('./Data.fs') dbroot = db.dbroot dbroot['a_number'] = 3 dbroot['a_string'] = 'Gift' dbroot['a_list'] = [1, 2, 3, 5, 7, 12] dbroot['a_dictionary'] = { 1918: 'Red Sox', 1919: 'Reds' } dbroot['deeply_nested'] = { 1918: [ ('Red Sox', 4), ('Cubs', 2) ], 1919: [ ('Reds', 5), ('White Sox', 3) ], } transaction.commit() db.close()
获取简单数据
from myzodb import MyZODB db = MyZODB('./Data.fs') dbroot = db.dbroot for key in dbroot.keys(): print key + ':', dbroot[key] db.close()运行结果:
注意:我们使用文件名"Data.fs"纯粹是为了遵循传统,因为许多ZODB安装在使用特定文件名方面实际上已经实现了标准化,你可以随心所欲地使用任何名称。
更改简单数据
当将某个键设置为新值,ZODB始终能够了解这一点。因此,对上面的数据库进行类型如下的更改将会自动别检测和持久化:
db = MyZODB('./Data.fs') dbroot = db.dbroot dbroot['a_string'] = 'Something Else' transaction.commit() db.close()但是,需要显示地将对列表或字典的更改告诉ZODB,因为ZODB无法了解所做的更改。这是持久性框架中的一个规定的可变性和参与功能。下面的代码不会导致ZODB看到更改:
a_dictionary = dbroot['a_dictionary'] a_dictionary[1920] = 'Indians' transaction.commit() db.close()
如果打算更改——而不是完全替换——类似如此的复杂对象,需要设置数据库根的属性 _p_changed,以通知它需要重新存储其下的属性:
a_dictionary = dbroot['a_dictionary'] a_dictionary[1920] = 'Indians' db._p_changed = 1 transaction.commit() db.close()
删除对象:
del dbroot['a_number'] transaction.commit() db.close()
注意:如果没有调用transaction.commit(),则上面更改都不会对数据库产生任何影响。正如在关系数据库中一样,只有通过提交已执行的操作,这些操作才会出现在数据库里。
持久化对象
当然,很少有Python程序员希望使用上面的诸如列表、元祖和字典等日益复杂的数据结构。相反,希望创建全能的Python对象,并且其属性将会自动地持久化。下面介绍如何定义一个可持久到数据库的类型。为此,该类将必须从Persistent继承。
from persistent import Persistent class Host(Persistent): def __init__(self, hostname, ip, interfaces): self.hostname = hostname self.ip = ip self.interfaces = interfaces
存储对象
现在可以创建该类的几个实例,并在ZODB中将其持久化:
from mymodel import Host host1 = Host('www.example.com', '192.168.7.2', ['eth0', 'eth1']) dbroot['www.example.com'] = host1 host2 = Host('dns.example.com', '192.168.7.4', ['eth0', 'gige0']) dbroot['dns.example.com'] = host2 transaction.commit() db.close()
获取对象
from mymodel import Host for key in dbroot.keys(): obj = dbroot[key] if isinstance(obj, Host): print "Host:", obj.hostname print " IP address:", obj.ip, " Interfaces:", obj.interfaces db.close()更改对象
正如“dhroot”对象能够自动检测在其键索引处放置的值一样,持久化对象将在您设置其属性时,自动执行检测,并将属性保存到数据库。
host = dbroot['www.example.com'] host.ip = '192.168.7.141' transaction.commit() db.close()
但是,如果您在某个对象下面存储复杂数据类型,则会出现与连接到数据根的复杂数据类型完全相同的问题。必须像前面一样设置 _p_changed 属性:
host = dbroot['www.example.com'] host.interfaces.append('eth2') host._p_changed = 1 transaction.commit() db.close()
最后,ZODB数据库实例很容易维护。由于ZODB数据库实例不包含需要设计或修改的模式,要执行的唯一例行维护是定期压缩以防止其耗尽整个磁盘。为了支持事务回滚,写到ZODB数据库的每个新的更改实际上都是追加到“Data.fs”文件,而不是更新该文件中已经存在的信息。要删除随着事务提交二积累的旧信息,ZODB管理员必须偶尔对其数据进行压缩。
注意:一次只有一个程序能够安全地打开“Data.fs”文件
参考地址:http://www.ibm.com/developerworks/cn/aix/library/au-zodb/
ZODB官方:http://www.zodb.org
相关文章推荐
- ZODB入门 -- 如何通过面向对象的动态语言 Python 使用对象数据库
- Python-数据库游标对象详解
- Python-数据库游标对象详解
- Python 数据库的Connection、Cursor两大对象
- Python 数据库的Connection、Cursor两大对象
- 详解python django面向关系数据库的ORM对象映射系统(1)
- python ORM 模块peewee(一): 建立数据库对象
- Python数据库操作、Python DB API、数据库连接对象connection、数据库游标对象cursor
- python ORM 模块peewee(一): 建立数据库对象
- python DB-API数据库常用对象及方法,postgresql为例
- python数据库编程(2) 游标对象cursor
- 详解Python 数据库的Connection、Cursor两大对象
- 使用 JDBC 创建数据库对象
- 对象-关系数据库之间的映射
- 使用 JDBC 创建数据库对象
- Com+和数据库访问对象(ADO.Net)的一些问题的研究(2002年12月10日)
- 对象数据库 VS 关系数据库
- 更改数据库所有者的对象
- 数据库对象命名规范
- 用VC存取数据库中的大对象