如何在带有 sqlite 后端的 zodb relstorage 中使用大于 1GB 的 blob?
How to use blobs > 1GB in zodb relstorage with sqlite backend?
我正在尝试通过 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"[=10=]" * 1024 ** 3)
在提交新创建的对象(在 db.transaction with 块的 __exit__
方法处)期间发生错误,并出现以下最终异常:
sqlite3.InterfaceError: Error binding parameter 2 - probably unsupported type.
保存大小为 1024 ** 2
的 blob 不会引发异常。
如何在不使用共享 blob 目录的情况下使用 relstorage 在 sqlite 后端保存 blob?
根据我的研究,您不能在此设置中存储任意大小的 blob。您正在达到 sqlite blob 大小限制 (https://www.sqlite.org/limits.html)。
你在这个阶段唯一的选择似乎是:
- 不要将 blob 存储在 sqlite 中,例如通过使用共享的 blob 目录。
- 增加 blob 限制,使用自定义构建的 sqlite(如上文所述link)。
- 减小存储的大小 - 例如通过压缩您的 blob,或将您的数据分成更小的 blob。
- 移动到不同的存储后端。
就我个人而言,如果我使用的是 sqlite,我会倾向于使用共享的 blob 目录,但是您已经取消了该选项,所以我认为您的选择是有限的。
I am trying to save a blob > 1GB via relstorage in a sqlite backend.
一个相关的答案是this一个。
我的建议是处理不同的大 blob(例如 2020 年大于 8 到 32MBytes)和小 blob。
大内容将保存为文件,您的 sqlite
数据库会知道(并存储)文件路径(例如某些生成的文件路径,例如 Linux 上的 /var/tmp/bigblob1234
。请参阅 hier(7) and inode(7)...)。
小内容将保存为 SQLITE blob。
当然你的 database schema and the Python code using it should be improved. Be aware of database normalization.
我正在尝试通过 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"[=10=]" * 1024 ** 3)
在提交新创建的对象(在 db.transaction with 块的 __exit__
方法处)期间发生错误,并出现以下最终异常:
sqlite3.InterfaceError: Error binding parameter 2 - probably unsupported type.
保存大小为 1024 ** 2
的 blob 不会引发异常。
如何在不使用共享 blob 目录的情况下使用 relstorage 在 sqlite 后端保存 blob?
根据我的研究,您不能在此设置中存储任意大小的 blob。您正在达到 sqlite blob 大小限制 (https://www.sqlite.org/limits.html)。
你在这个阶段唯一的选择似乎是:
- 不要将 blob 存储在 sqlite 中,例如通过使用共享的 blob 目录。
- 增加 blob 限制,使用自定义构建的 sqlite(如上文所述link)。
- 减小存储的大小 - 例如通过压缩您的 blob,或将您的数据分成更小的 blob。
- 移动到不同的存储后端。
就我个人而言,如果我使用的是 sqlite,我会倾向于使用共享的 blob 目录,但是您已经取消了该选项,所以我认为您的选择是有限的。
I am trying to save a blob > 1GB via relstorage in a sqlite backend.
一个相关的答案是this一个。
我的建议是处理不同的大 blob(例如 2020 年大于 8 到 32MBytes)和小 blob。
大内容将保存为文件,您的 sqlite
数据库会知道(并存储)文件路径(例如某些生成的文件路径,例如 Linux 上的 /var/tmp/bigblob1234
。请参阅 hier(7) and inode(7)...)。
小内容将保存为 SQLITE blob。
当然你的 database schema and the Python code using it should be improved. Be aware of database normalization.