Как использовать капли> 1 ГБ в хранилище zodb с серверной частью sqlite?
Я пытаюсь сохранить blob > 1 ГБ через relstorage в серверной части sqlite. Следующий минимальный рабочий пример
- удаляет все ранее созданные базы данных вместе с каталогом больших двоичных объектов,
- создать новую базу данных и
- сохраняет в базе данных большой двоичный объект размером 1 ГБ.
Минимальный рабочий пример:
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 - вероятно, неподдерживаемый тип.
Сохранение капли с размером
1024 ** 2
не вызывает исключения.
Как можно сохранить большой двоичный объект в серверной части sqlite с помощью relstorage без использования общего каталога больших двоичных объектов?
2 ответа
Согласно моим исследованиям, в этой настройке нельзя хранить капли произвольного размера. Вы достигли предела размера большого двоичного объекта sqlite (https://www.sqlite.org/limits.html).
На этом этапе у вас есть единственные варианты:
- Не храните большой двоичный объект в sqlite, например, используя общий каталог больших двоичных объектов.
- Увеличьте лимит больших двоичных объектов, используя настраиваемую сборку sqlite (как описано в приведенной выше ссылке).
- Уменьшите размер того, что вы храните, например, сжав свои капли или разбив данные на более мелкие капли.
- Перенести в другую серверную часть хранилища.
Лично я был бы склонен использовать общий каталог blob, если бы я использовал sqlite, но вы отказались от этой опции, поэтому я думаю, что ваш выбор ограничен.
Я пытаюсь сохранить blob > 1 ГБ через relstorage в серверной части sqlite.
Связанный ответ это один.
Я предлагаю обрабатывать разные большие двоичные объекты (например, размером от 8 до 32 МБ в 2020 году) и маленькие.
Большой контент будет сохранен в виде файлов, а ваш
sqlite
база данных будет знать (и хранить) путь к файлу (например, некоторый сгенерированный путь к файлу, такой как
/var/tmp/bigblob1234
в Linux. Смотрите hier(7) и inode(7)...).
Небольшой контент будет сохранен как капли SQLITE.
Конечно, необходимо улучшить как схему вашей базы данных, так и код Python, использующий ее. Помните о нормализации базы данных.