Как использовать капли> 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).

На этом этапе у вас есть единственные варианты:

  1. Не храните большой двоичный объект в sqlite, например, используя общий каталог больших двоичных объектов.
  2. Увеличьте лимит больших двоичных объектов, используя настраиваемую сборку sqlite (как описано в приведенной выше ссылке).
  3. Уменьшите размер того, что вы храните, например, сжав свои капли или разбив данные на более мелкие капли.
  4. Перенести в другую серверную часть хранилища.

Лично я был бы склонен использовать общий каталог blob, если бы я использовал sqlite, но вы отказались от этой опции, поэтому я думаю, что ваш выбор ограничен.

Я пытаюсь сохранить blob > 1 ГБ через relstorage в серверной части sqlite.

Связанный ответ это один.

Я предлагаю обрабатывать разные большие двоичные объекты (например, размером от 8 до 32 МБ в 2020 году) и маленькие.

Большой контент будет сохранен в виде файлов, а ваш sqlite база данных будет знать (и хранить) путь к файлу (например, некоторый сгенерированный путь к файлу, такой как /var/tmp/bigblob1234в Linux. Смотрите hier(7) и inode(7)...).

Небольшой контент будет сохранен как капли SQLITE.

Конечно, необходимо улучшить как схему вашей базы данных, так и код Python, использующий ее. Помните о нормализации базы данных.

Другие вопросы по тегам