ZODB python:如何避免创建只有一个大条目的数据库?

ZODB python: how to avoid creating a database with only one big entry?

我是第一次使用 ZODB python 数据库 模块。教程 (http://www.zodb.org/en/latest/tutorial.html) 让我对 ZODB 数据库行为的某个方面感到困惑:如何避免不小心创建一个只有一个非常大的条目的数据库?我将逐步解释我的应用程序、我当前的数据库方法以及混淆的来源。


1。项目对象

我要保存的数据库完全由Item对象组成,定义如下(稍微简化):

class Item(Persistent):
    def __init__(self, name, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # 1. Persistent variables
        # ------------------------
        self.__name = name
        self.__myList = PersistentList()   # <- list can hold other Item-objects

        self.__myVar01 = None
        self.__myVar02 = None
        self.__myVar03 = None

        # 2. Non-persistent variables
        # ----------------------------
        self._v_myVar01 = None
        self._v_myVar02 = None
        self._v_myVar03 = None

直观表示如下:


应用程序在启动时构造一个这样的 Item 对象。在应用程序期间,此 Item 对象将创建 'children'(它们本身也是 Item 对象)。这个过程持续了一段时间,使得以下对象结构在内存中:


这个构造可以很容易地包含 20.000 个 Item-对象。所以我想将它们保存在数据库中。


2。我如何将此结构保存到 ZODB 数据库

为了将这种 Item-objects 结构保存在数据库中,我遵循了教程中的以下指南:

Storing objects
To store an object in the ZODB we simply attach it to any other object that already lives in the database. Hence, the root object functions as a boot-strapping point. The root object is meant to serve as a namespace for top-level objects in your database.
[ Quoted from ZODB Tutorial   http://www.zodb.org/en/latest/tutorial.html ]

以下函数创建一个新数据库(从顶级项目开始)并将其保存到硬盘:

from ZODB.FileStorage import FileStorage
from ZODB import DB
from persistent import Persistent
import transaction

# Call this function to save the database
# to the harddrive and close it.
# ----------------------------------------
def save_database_and_close():
    transaction.commit()
    conn.close()
    db.close()

# Call this function to create a new
# database, starting from a root-item
# ------------------------------------
def create_database(root_item):
    storage = FileStorage("C:/mytest/mydb.db")
    db = DB(storage)
    conn = db.open()
    root = conn.root()
    root.myRootItem = root_item
    transaction.commit()


3。将所有内容存储在根上的问题

但是 - 在继续阅读教程时 - 我觉得我目前的方法不是很好:

(Please note that at this point, the tutorial has covered an example of making Account-objects to be stored in a ZODB database)

We could store Account-objects directly on the root object:

import account

# Probably a bad idea:
root.account1 = account.Account()

But if you’re going to store many objects, you’ll want to use a collection object 3:

import account, BTrees.OOBTree

root.accounts = BTrees.OOBTree.BTree()
root.accounts['account-1'] = Account()

Footnote 3:
The root object is a fairy simple persistent object that’s stored in a single database record. If you stored many objects in it, its database record would become very large, causing updates to be inefficient and causing memory to be used ineffeciently.

脚注暗示我只是在创建一个包含一个大条目的数据库——这当然是您能想象到的最低效的数据库类型。


4。我困惑的地方

好吧,我很确定下面的方法是非常糟糕的(并被上面的警告所谴责):


但是这个警告(不要将所有内容都存储在根目录中)是否也适用于我的情况?像这样:

换句话说,我的方法是否会创建一个包含单个大条目的数据库(效率非常低)?或者它会创建一个很好的数据库,每个 Item-object 有一个条目?


注:
我不确定它是否相关,但我会在这里列出我的系统规格:

不,这并不低效。 ZODB 为每个 Persistent 个实例 创建 单独的条目。这些条目稍后会在您访问它们时按需加载。

来自您链接到的同一教程:

Subclassing Persistent provides a number of features:

[...]

  • Data will be saved in its own database record.

这对您的应用程序来说是完全透明的。您的第一笔交易会很大,但后续交易只会在您更改时写出对个别项目的更改。