【问题标题】:ZODB python: how to avoid creating a database with only one big entry?ZODB python:如何避免创建只有一个大条目的数据库?
【发布时间】:2018-05-21 09:36:15
【问题描述】:

我是第一次使用 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-object 将创建“children”(它们本身也是 Item-objects)。这个过程会持续一段时间,因此以下对象结构在内存中:

 
这个结构可以很容易地由 20.000 个Item 对象组成。所以我想将它们保存在数据库中。

 

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

为了将项目对象的这种结构保存在数据库中,我遵循教程中的以下指南:

存储对象
要将对象存储在 ZODB 中,我们只需将其附加到已存在于数据库中的任何其他对象。因此,根对象用作引导点。根对象用作数据库中顶级对象的命名空间。
[引自 ZODB 教程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。将所有内容存储在根目录上的问题

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

(请注意,此时,本教程已经介绍了将 Account-对象存储在 ZODB 数据库中的示例)

我们可以将帐户-对象直接存储在根对象上:

import account

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

但是如果你要存储很多对象,你会想要使用一个集合对象3

import account, BTrees.OOBTree

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

脚注3
根对象是一个简单的持久对象,存储在单个数据库记录中。如果你在其中存储了很多对象,它的数据库记录会变得非常大,导致更新效率低下,导致内存使用效率低。

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

 

4。我对什么感到困惑

好的,我很确定以下方法非常糟糕(并受到上述警告的谴责):

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

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


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

  • Windows 10,64 位
  • Python 3.6.3
  • ZODB 5.4.0(截至目前的最新版本 - 2018 年 5 月 21 日)

【问题讨论】:

    标签: python database python-3.x python-3.6 zodb


    【解决方案1】:

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

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

    子类化Persistent 提供了许多功能:

    [...]

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

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

    【讨论】:

    • 谢谢先生!所以我可以确信每个 Item-object 在数据库中都有自己的记录:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 2023-02-20
    相关资源
    最近更新 更多