1. 什么是对象数据库
关系型数据库,是指采用了关系模型来组织数据的数据库,以行和列的形式存储数据库,典型如mysql。
NoSQL数据库,是指非关系型数据库,典型如mongodb。
对象数据库,是一种以对象形式表示信息的数据库,对于关系型数据库,你必须事先定义一张表,在写入数据时,必须通过sql语句按照表的定义写入字段值;对于NoSQL数据库,已经没有了表的概念,你实现不需要做任何定义,可以将python字典直接写入mongodb,每次写入的字典里,key的数量和内容都可以不同, NoSQL在操作上已经方便了不少,但还是要将数据统一转成字典才可以;而对象数据库,可以将python的对象写入其中,包括基础数据类型和自定义类创建的对象,如此一来,就更加方便了。
pickle模块可以对python对象进行序列化操作,可以序列化到文件中,但它不能称之为对象数据库,它只是一个序列化工具。
2. zodb
zodb是python实现的一个本地的对象数据库,它依赖persistent模块,这个模块实现了通用的对象序列化方法。
使用pip安装
pip install ZODB
2.1 创建数据库
可以创建基于文件存储的数据库
import ZODB, ZODB.FileStorage
storage = ZODB.FileStorage.FileStorage('mydata.fs')
db = ZODB.DB(storage)
还可以创建基于内存的数据库
import ZODB
db = ZODB.DB(None)
如果你想持久化存储数据,应该创建基于文件的数据库。
2.2 获得数据库连接
connection = db.open()
2.3 存储数据
import transaction
root = connection.root()
root['employees'] = ['Mary', 'Jo', 'Bob']
transaction.commit()
db.close()
一定要加上transaction.commit()
2.4 查询数据
print(root['employees'])
看起来,root更像是一个字典。
3. 存储自定义类创建的对象
如果只是存储一些基础数据类型,这个库也就没有什么亮点了,想要存储自定义类的创建的对象,这个自定义类必须继承persistent.Persistent ,persistent
import persistent
class Account(persistent.Persistent):
def __init__(self):
self.balance = 0.0
def deposit(self, amount):
self.balance += amount
def cash(self, amount):
assert amount < self.balance
self.balance -= amount
存储自定义类创建的对象和存储基础数据类型的方法一致
import ZODB, ZODB.FileStorage
import transaction
from account import Account
storage = ZODB.FileStorage.FileStorage('mydata.fs')
db = ZODB.DB(storage)
connection = db.open()
root = connection.root()
def store():
account1 = Account()
account1.deposit(100)
#
root['account1'] = account1
transaction.commit()
db.close()
def search():
print(root['account1'].balance)
store()
search() # 100.0
如果一个类继承了persistent.Persistent,那么在定义属性时就要注意,对于可变类型对象要特殊处理
class Employee(Persistent):
def __init__(self):
self.tasks = []
def setName(self, name):
self.name = name
def addTask(self, task):
self.task.append(task)
self._p_changed = 1
属性task的类型是列表,可变对象,在对可变对象进行修改时,必须主动的设置_p_changed属性为1,否则将不能正常存储到zodb中。如果你不想这么麻烦,可以用PersistentList类替换原生的list,这样就不需要修改_p_changed的值了。
import persistent.list
class Employee(Persistent):
def __init__(self):
self.tasks = persistent.list.PersistentList()
def addTask(self, task):
self.task.append(task)
4. 什么情况下使用zodb
如果你的应用里,有一些数据需要存储,而这些数据并不值得你为他们专门创建一张表,而且数据量并不是非常大,那么zodb和适合你。如果对于数据,你有很强的搜索需要和相对复杂的运算需求,那么不要使用zodb。