База данных объектов Zope
Разработчик(и) | Фонд Зопе |
---|---|
Стабильная версия | 5.8.1 [ 1 ]
/ 18 июля 2023 г |
Репозиторий | github |
Написано в | Питон |
Операционная система | Кросс-платформенный |
Тип | База данных объектов |
Лицензия | Общественная лицензия Zope |
Веб-сайт | www |
База данных объектов Zope ( ZODB ) — это объектно-ориентированная база данных для прозрачного и постоянного хранения объектов Python . Он включен как часть Zope сервера веб- приложений , но его также можно использовать независимо от Zope.
Возможности ZODB включают в себя: транзакции, историю/отмену, прозрачно подключаемое хранилище, встроенное кэширование, управление многоверсионным параллелизмом (MVCC) и масштабируемость по сети (с использованием ЗЕО ).
История
[ редактировать ]База данных объектов Zope (ZODB) была создана Джимом Фултоном из Zope Corporation в конце 1990-х годов. Первоначально он начинался как простая система постоянных объектов (POS) во время разработки Principia, которая позже превратилась в Zope. Значительное архитектурное изменение привело к переименованию системы в ZODB 3. Впоследствии ZODB 4 был представлен как недолговечный проект, направленный на повторную реализацию всего пакета ZODB 3 с использованием 100% Python.
Выполнение
[ редактировать ]Основы
[ редактировать ]ZODB хранит объекты Python, используя расширенную версию встроенного механизма сохранения объектов Python (pickle). База данных ZODB имеет единственный корневой объект (обычно словарь), который является единственным объектом, к которому база данных имеет прямой доступ. Доступ ко всем остальным объектам, хранящимся в базе данных, осуществляется через корневой объект. Объекты, на которые ссылается объект, хранящийся в базе данных, также автоматически сохраняются в базе данных.
ZODB поддерживает параллельные транзакции с использованием MVCC и отслеживает изменения объектов отдельно для каждого объекта. Фиксируются только измененные объекты. Транзакции по умолчанию являются неразрушающими и могут быть отменены.
Пример
[ редактировать ]Например, предположим, что у нас есть автомобиль, описанный с использованием 3 классов. Car
, Wheel
и Screw
. В Python это можно представить следующим образом:
class Car: [...]
class Wheel: [...]
class Screw: [...]
myCar = Car()
myCar.wheel1 = Wheel()
myCar.wheel2 = Wheel()
for wheel in (myCar.wheel1, myCar.wheel2):
wheel.screws = [Screw(), Screw()]
Если переменная mycar является корнем персистентности, то:
zodb['mycar'] = myCar
При этом все экземпляры объектов (автомобиль, колесо, винты и т. д.) помещаются в хранилище, которое можно будет получить позже. Если другая программа подключается к базе данных через объект mycar, выполняя:
car = zodb['myCar']
И извлекает все объекты, указатель на автомобиль находится в car
переменная. Затем, на более позднем этапе, этот объект можно изменить с помощью кода Python, например:
car.wheel3 = Wheel()
car.wheel3.screws = [Screw()]
Хранилище изменяется, чтобы отразить изменение данных (после заказа фиксации).
Ни в Python, ни в ZODB нет объявления структуры данных, поэтому новые поля можно свободно добавлять к любому существующему объекту.
Единица хранения
[ редактировать ]Чтобы сохраняемость имела место, класс Python Car должен быть производным от персистентности. Постоянный класс — этот класс не только содержит данные, необходимые для работы механизма персистентности, такие как внутренний идентификатор объекта, состояние объекта и т. д., но также определяет границу персистентности в следующем смысле: каждый объект, класс которого происходит от Persistent — это атомарная единица хранения (весь объект копируется в хранилище при изменении поля).
В приведенном выше примере, если Car
— единственный класс, производный от Persistent, когда wheel3
добавляется в автомобиль, все объекты должны быть записаны в хранилище. Напротив, если Wheel
также происходит от Persistent, тогда, когда carzz.wheel3 = Wheel
выполняется, в хранилище записывается новая запись, содержащая новое значение Car
, но существующие Wheel
сохраняются, и новый рекорд для Car
указывает на уже существующее Wheel
запись внутри хранилища.
Механизм ZODB не отслеживает изменения по графу указателей. В приведенном выше примере carzz.wheel3 = something
это модификация, автоматически отслеживаемая механизмами ZODB, поскольку carzz
имеет (постоянный) класс Car
. Механизм ZODB делает это, помечая запись как dirty
. Однако, если список существует, любые изменения внутри списка не замечаются механизмом ZODB, и программист должен помочь, добавив вручную carzz._p_changed = 1
, уведомляя ZODB о том, что запись действительно изменилась. Таким образом, в определенной степени программист должен знать о работе механизма сохранения.
атомарность
[ редактировать ]Единица хранения (то есть объект, класс которого является производным от Persistent) также является единицей атомарности . В приведенном выше примере, если Cars
является единственным постоянным классом, поток изменяет колесо ( Car
запись должна быть уведомлена), и другой поток изменяет другой Wheel
внутри другой транзакции вторая фиксация завершится неудачей. Если Wheel
также является постоянным, оба Wheels
может быть изменен независимо двумя разными потоками в двух разных транзакциях.
Сохранение класса
[ редактировать ]Сохранение класса — запись класса конкретного объекта в хранилище — достигается путем записи своего рода «полного» имени класса в каждую запись на диске. В Python имя класса включает в себя иерархию каталогов, в которых находится исходный файл класса. Следствием этого является то, что исходный файл постоянного объекта не может быть перемещен. Если это так, механизм ZODB не может определить класс объекта при извлечении его из хранилища, что приводит к поломке объекта.
ЗЕО
[ редактировать ]Zope Enterprise Objects (ZEO) — это реализация хранилища ZODB, которая позволяет нескольким клиентским процессам сохранять объекты на одном сервере ZEO. Это облегчает прозрачное масштабирование.
Подключаемые хранилища
[ редактировать ]Сетевое хранилище (также известное как ZEO) позволяет нескольким процессам Python одновременно загружать и сохранять постоянные экземпляры. Хранилище файлов позволяет одному процессу Python взаимодействовать с файлом на диске. RelStorage позволяет резервному хранилищу персистентности быть RDBMS . Directory Storage хранит все постоянные данные в виде отдельного файла в файловой системе, аналогично FSFS в Subversion . Демонстрационное хранилище служит серверной частью в памяти для постоянного хранилища. BDBStorage, ныне заброшенный, использовал серверную часть Berkeley DB .
аварийного переключения Технологии
[ редактировать ]Zope Replication Services (ZRS) — это коммерческое дополнение, открытое с мая 2013 года, которое устраняет единую точку отказа, обеспечивая горячее резервное копирование для записи и балансировку нагрузки для чтения. ZeoRAID — это решение с открытым исходным кодом, предлагающее сетевой прокси-сервер, который распределяет хранилища объектов и средства восстановления между несколькими сетевыми серверами. RelStorage, используя технологии РСУБД, устраняет необходимость в сервере ZEO. NEO — это реализация распределенного хранилища, обеспечивающая отказоустойчивость и балансировку нагрузки.