ZODB – объектная база данных

онлайн тренер по питону
Онлайн-тренажер Python 3 для начинающих

Теория без воды. Задачи с автоматической проверкой. Подсказки на русском языке. Работает в любом современном браузере.

начать бесплатно

Введение

Большинство современных баз данных требует преобразования Python-объектов в строки, таблицы или JSON перед сохранением. Это усложняет архитектуру приложений и требует дополнительного кода. ZODB – объектная база данных решает эту проблему, позволяя сохранять Python-объекты "как есть".

ZODB (Zope Object Database) — это прозрачная, нативная объектная база данных, полностью реализованная на Python. Она не требует схемы, не использует SQL, поддерживает транзакции и позволяет работать с объектами напрямую, как с обычными переменными.

Установка и настройка ZODB

Установка через pip:

bash
pip install ZODB

Основные компоненты:

  • FileStorage — хранение базы в файле

  • DB — интерфейс базы

  • Connection — подключение к объектам

  • transaction — модуль для управления транзакциями

Принцип работы объектной базы данных

  • Сохраняются Python-объекты со всеми атрибутами и методами

  • Используется сериализация на основе pickle, но с добавлением прозрачного управления изменениями

  • Изменения отслеживаются автоматически

Создание и использование объектов

Все объекты, которые нужно сохранять, должны наследоваться от Persistent:

python
from persistent import Persistent class Person(Persistent): def __init__(self, name): self.name = name

Запись и чтение данных

Создание базы и сохранение объекта:

python
from ZODB import FileStorage, DB import transaction storage = FileStorage.FileStorage('mydata.fs') db = DB(storage) conn = db.open() root = conn.root() root['person'] = Person("Иван") transaction.commit()

Загрузка данных:

python
print(root['person'].name)

Структура базы и корневой объект

Каждая база имеет корневой объект (root()), который обычно представляет собой словарь (persistent.mapping.PersistentMapping).

Он используется как входная точка:

python
root['users'] = {}

Модификация и удаление данных

python
root['person'].name = "Анна" transaction.commit() del root['person'] transaction.commit()

Изменения отслеживаются автоматически — вам не нужно вручную отмечать поля как изменённые.

Поддержка транзакций и отката

ZODB поддерживает полноценные транзакции:

python
transaction.commit() # сохранение изменений transaction.abort() # откат

Можно также использовать with transaction.manager::

python
with transaction.manager: root['x'] = 42

Работа с несколькими объектами и ссылками

ZODB позволяет создавать ссылки между объектами. При сохранении одного объекта сохраняются и все связанные:

python
class Group(Persistent): def __init__(self): self.members = [] group = Group() group.members.append(root['person']) root['group'] = group transaction.commit()

ZEO – клиент-серверный режим ZODB

Для многопользовательского доступа к базе используется ZEO (Zope Enterprise Objects):

bash
pip install ZEO
  • Сервер запускается отдельно

  • Клиенты подключаются к базе по TCP

  • Поддерживается параллельная работа, блокировки, консистентность

Хранение в памяти и временные базы

Для тестирования:

python
from ZODB.DemoStorage import DemoStorage storage = DemoStorage() db = DB(storage)

Полностью работает в памяти, база удаляется после закрытия.

Совместимость с другими библиотеками

ZODB отлично работает с:

  • BTrees — эффективные структуры поиска

  • ZCatalog — полнотекстовый поиск

  • ZEO — масштабирование

Но объекты должны быть сериализуемы через pickle — нельзя сохранять, например, сокеты или внешние подключения.

Сценарии применения ZODB

  • Веб-приложения (Plone, Pyramid)

  • Хранение сессий и кэша

  • Сложные доменные модели с множеством объектов

  • IoT-устройства с объектной логикой

Сравнение с другими решениями

СУБД Тип Поддержка Python-объектов Транзакции SQL
ZODB Объектная Полная Да Нет
SQLite Реляционная Нет Да Да
MongoDB Документная Частично (через dict) Да Нет
PickleDB Ключ-значение Частично Нет Нет

Тестирование с ZODB

python
from ZODB.DemoStorage import DemoStorage from ZODB import DB db = DB(DemoStorage()) conn = db.open() root = conn.root()

Используйте transaction.abort() для сброса изменений.

Часто задаваемые вопросы (FAQ)

1. Что такое ZODB?
Это объектная база данных на Python, позволяющая сохранять Python-объекты напрямую.

2. Чем она отличается от SQL?
Не требует схемы, не использует SQL, работает с объектами.

3. Поддерживает ли ZODB транзакции?
Да, через модуль transaction.

4. Можно ли использовать ZODB в веб-приложениях?
Да, особенно с Pyramid и Plone.

5. Есть ли асинхронная поддержка?
Нет, ZODB синхронная, но может использоваться в ThreadPool.

6. Безопасна ли ZODB для продакшена?
Да, особенно с использованием ZEO и резервного копирования.

Полный справочник по работе с ZODB — объектно-ориентированной базой данных для Python

Установка

bash
pip install ZODB

Также рекомендуется:

bash
pip install ZODB[persistent]

Основные особенности

Возможность Описание
Хранит Python-объекты напрямую Без преобразования в таблицы или JSON.
Поддержка транзакций Как в полноценной СУБД.
Поддержка индексов, ссылок, вложенности В объектах.
Подходит для встраивания Работает как встроенное хранилище.
Нет SQL Объектно-ориентированный подход.

Быстрый пример

python
import ZODB, ZODB.FileStorage import persistent import transaction class Person(persistent.Persistent): def __init__(self, name): self.name = name storage = ZODB.FileStorage.FileStorage('data.fs') db = ZODB.DB(storage) connection = db.open() root = connection.root() root['alice'] = Person("Alice") transaction.commit() connection.close() db.close()

Ключевые модули

Модуль Назначение
persistent.Persistent Базовый класс для сохранения объектов.
transaction Работа с транзакциями.
ZODB.DB, ZODB.FileStorage Создание базы и файлового хранилища.

Работа с корневым хранилищем

python
connection = db.open() root = connection.root() root['key'] = some_persistent_object transaction.commit()

Изменение объектов

Чтобы изменения сохранялись — объект должен быть унаследован от persistent.Persistent, и его поля нужно явно помечать изменёнными:

python
class Person(persistent.Persistent): def set_name(self, new_name): self.name = new_name self._p_changed = True # обязательно person = root['alice'] person.set_name("Alicia") transaction.commit()

Использование persistent.mapping.PersistentMapping

Это аналог dict, но с поддержкой ZODB:

python
from persistent.mapping import PersistentMapping root['users'] = PersistentMapping() root['users']['admin'] = Person("Admin") transaction.commit()

Удаление объектов

python
del root['alice'] transaction.commit()

Загрузка и повторное подключение

python
db = ZODB.DB(ZODB.FileStorage.FileStorage('data.fs')) connection = db.open() root = connection.root() print(root['alice'].name)

Поддержка вложенных объектов и связей

ZODB поддерживает ссылки между объектами, включая вложенные структуры:

python
class Department(persistent.Persistent): def __init__(self, name): self.name = name self.employees = [] dept = Department("IT") dept.employees.append(Person("Bob")) root['dept'] = dept transaction.commit()

Сериализация и бинарные данные

ZODB использует pickle для сериализации. Следует быть осторожным с:

  • нестабильными структурами (lambda, open файлов, сокетов);

  • сторонними классами без поддержки pickle.


Удаление базы

Просто удалите файлы:

  • data.fs

  • data.fs.index

  • data.fs.lock

  • data.fs.tmp


Когда использовать ZODB

  • Когда приложение уже работает с Python-объектами, и нет смысла создавать ORM.

  • В настольных приложениях, CLI-утилитах, ботах, кэшах и инструментах.

  • Если вы хотите простой, встроенный, типобезопасный способ хранения данных.

  • При необходимости персистентности в Python-прототипах.


Недостатки

Недостаток Комментарий
Нет SQL / индексов Запросы осуществляются через обход и Python-код.
Не для масштабируемых систем Не рассчитан на многопоточность и кластеры.
Нет встроенной схемы миграции Всё контролируется вручную.

Заключение

ZODB – объектная база данных предоставляет уникальный подход к хранению данных в Python. Она позволяет сохранять объекты "как есть", работать без схем, таблиц и SQL-запросов. Благодаря своей простоте, прозрачности и поддержке транзакций ZODB отлично подходит для Python-разработчиков, которым важна нативность и гибкость модели данных.