zodb,一个python对象数据库

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。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案