0

我正在尝试通过relstorage在 sqlite 后端保存一个 > 1GB 的 blob。以下最小工作示例

  • 删除任何先前创建的数据库以及 blob 目录,
  • 创建一个新的数据库和
  • 将 1GB 的 blob 保存到数据库中。

最小工作示例:

import os
import shutil
from ZODB import blob, config

connectionString = """
%import relstorage
<zodb main>
<relstorage>
    blob-dir blob
    keep-history false
    cache-local-mb 0
    <sqlite3>
        data-dir .
    </sqlite3>
</relstorage>
</zodb>
"""

# cleaning up
for x in os.listdir():
    if "sqlite" in x:
        os.remove(x)

shutil.rmtree("blob", True)

# creating database
db = config.databaseFromString(connectionString)

with db.transaction() as conn:
    conn.root.blob = blob.Blob()
    with conn.root.blob.open("w") as f:
        f.write(b"\0" * 1024 ** 3)

在新创建的对象的提交期间(在__exit__db.transaction with-block 的方法中)发生错误,并出现以下最终异常:

sqlite3.InterfaceError:错误绑定参数 2 - 可能是不受支持的类型。

保存具有大小的 blob1024 ** 2不会引发异常。

如何在不使用共享 blob 目录的情况下使用 relstorage 将 blob 保存在 sqlite 后端?

4

2 回答 2

3

根据我的研究,您不能在此设置中存储任意大小的 blob。您正在达到 sqlite blob 大小限制(https://www.sqlite.org/limits.html)。

在这个阶段你唯一的选择似乎是:

  1. 不要将 blob 存储在 sqlite 中,例如使用共享的 blob 目录。
  2. 使用 sqlite 的自定义构建增加 blob 限制(如上面的链接中所述)。
  3. 减少您存储的内容的大小 - 例如通过压缩您的 blob,或将您的数据分块为更小的 blob。
  4. 移动到不同的存储后端。

就个人而言,如果我使用 sqlite,我会倾向于使用共享 blob 目录,但你已经打折了这个选项,所以我认为你的选择是有限的。

于 2020-10-17T14:18:50.793 回答
0

我正在尝试通过 relstorage 在 sqlite 后端保存一个 > 1GB 的 blob。

一个相关的答案是这个

我的建议是处理不同的大 blob(例如,2020 年大于 8 到 32MBytes)和小 blob。

大型内容将保存为文件,您的sqlite数据库将知道(并存储)文件路径(例如,某些生成的文件路径,例如/var/tmp/bigblob1234在 Linux 上。参见hier(7)inode(7) ...)。

小内容将保存为 SQLITE blob。

当然,您的数据库模式和使用它的 Python 代码都应该得到改进。注意数据库规范化

于 2020-10-19T08:49:56.277 回答