Объектно-ориентированная база данных ZODB

obektno orientirovannaya baza dannyh zodb Базы данных и постоянное хранение

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

ZODB — не единственная объектно-ориентированная база данных, доступная для программ на языке Python: система Durus в целом выглядит проще и во многом подобна ZODB. Однако, несмотря на некоторые преимущества, в настоящее время Durus не предлагает всех особенностей, имеющихся в ZODB, и используется не так широко (возможно просто потому, что является более новой). По этой причине концепции объектно-ориентированных баз данных будут рассматриваться в этом разделе на примере ZODB.

ZODB — это открытое, стороннее расширение для Python. Первоначально этот продукт разрабатывался как механизм базы данных для веб-сайтов в составе веб-фреймворка Zope, упоминавшегося в главе 12, но теперь он доступен в виде самостоятельного пакета. Его можно использовать во многих областях вне контекста Zope и Веб как универсальную систему управления базами данных.

ZODB не поддерживает язык запросов SQL, однако объекты, хранимые в этой базе данных, могут использовать всю мощь языка Python. Кроме того, в некоторых приложениях хранимые данные более естественно представлять в виде структурированных объектов Python. Реляционные системы, основанные на таблицах, часто вынуждены представлять такие данные в виде отдельных фрагментов, разбросанных по нескольким таблицам и связанных сложными, порой весьма медлительными в обработке соединениями по ключу, или как-то иначе отображать их в модель классов языка Python. Поскольку объектно-ориентированные базы данных сохраняют объекты Python непосредственно, они часто способны обеспечить более простую модель в виде систем, не требующих использования мощного языка SQL.

Принцип работы с базой данных ZODB очень близко напоминает работу с хранилищами, создаваемыми стандартным модулем shelve, описанными в предыдущем разделе. Так же как и модуль shelve, для реализации постоянно хранимых словарей с хранимыми объектами Python ZODB использует систему сериализации Python. Фактически база данных почти не имеет специализированного интерфейса — объекты сохраняются в ней за счет простого присваивания по ключу объекту корневого словаря ZODB или за счет встраивания их в объекты, хранящиеся в корне базы данных. И, как и в случае с модулем shelve, «записи» имеют вид обычных объектов Python, обрабатываемых с помощью обычного синтаксиса и инструментов Python.

Однако, в отличие от модуля shelve, ZODB добавляет особенности, имеющие большое значение для некоторых программ:

Возможность одновременного обновления

Вам не придется вручную блокировать доступ к файлам, чтобы избежать повреждения данных при наличии нескольких пишущих процессов, что необходимо при использовании модуля shelve.

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

При аварийном завершении программы изменения не будут сохранены в базе данных, если они не были явно подтверждены.

Ав тома ти че ское сохра не ние изме не ний для не ко торых ти пов объ ектов в памяти

Объекты в ZODB, порожденные от суперкласса постоянно хранимых объектов, достаточно сообразительны, чтобы знать, когда можно обновить содержимое в базе данных при присваивании значений их атрибутам.

Ав тома ти че ское кэ широ ва ние объ ек тов

Для большей эффективности объекты кэшируются в памяти и автоматически удаляются из кэша, когда надобность в них отпадает.

Плат формо не за ви си мое хра ни ли ще

Все данные ZODB хранит в одном плоском файле и поддерживает файлы большого размера, поэтому она не подвержена ограничениям на размер файлов и проблемам из-за различий в форматах DBM, свойственных модулю shelve. Как мы видели ранее в этой главе, хранилище, созданное в Windows с использованием bsddb, может ока-

заться недоступным для сценариев, выполняющихся в Linux и использующих gdbm.

Благодаря этим преимуществам ZODB определенно заслуживает внимания, если вам потребуется постоянно сохранять объекты Python в базе данных при промышленной эксплуатации. Единственное, чем придется заплатить за использование ZODB, — это небольшой объем дополнительного программного кода:

     Для организации доступа к базе данных ZODB необходим некоторый объем типового программного кода — это не просто вызов функции открытия.

     Классы должны наследовать суперкласс постоянно хранимых объектов, если вы пожелаете воспользоваться преимуществом автоматического обновления при их изменении — классы постоянно хранимых объектов в целом не являются полностью независимыми от базы данных, как и при использовании модуля shelve, хотя это в принципе возможно.

Во многих приложениях эти недостатки с лихвой окупаются дополнительными возможностями, предоставляемыми системой ZODB сверх того, что дает модуль shelve.

Сильно сокращенный учебник по ZODB

К сожалению, когда я писал эти строки, в июне 2010 года, еще отсутствовала версия ZODB для Python 3.X. Вследствие этого примеры и описание версии для Python 2.X, присутствовавшие в предыдущем издании, были убраны из этого раздела. Однако из уважения к пользователям Python 2.X, а также к читателям, использующим Python 3.X и ждущим, когда материализуется версия ZODB 3.X, я добавил материалы и примеры из прошлого издания, касающиеся ZODB, в пакет примеров для этого издания.

Дополнительную информацию о пакете с примерами вы найдете в предисловии, и ищите информацию о ZODB в следующих каталогах:

C:\\Dbase\Zodb-2.x # примеры использования ZODB из 3 издания

C:\\Dbase\Zodb-2.x\Documentaion # Учебник по ZODB из 3 издания

Хотя я не умею предсказывать будущее, тем не менее ZODB для Python 3.X наверняка появится рано или поздно. Но пока ее нет, можно использовать другие объектно-ориентированные базы данных для Python 3.X, предлагающие некоторые дополнительные возможности.

Однако, чтобы дать вам некоторое представление о ZODB, мы кратко познакомимся с особенностями ее использования в Python 2.X. После установки поддержки ZODB в первую очередь необходимо создать базу данных:

\PP4E\Dbase\Zodb-2.x> python

>  >> from ZODB import FileStorage, DB

>  >> storage = FileStorage.FileStorage(r’C:\temp\mydb.fs’)

>  >> db = DB(storage)

>  >> connection = db.open()

>  >> root = connection.root()

Это практически стандартный, «типовой» программный код, выполняющий подключение к базе данных ZODB: здесь импортируются необходимые инструменты, создаются объекты классов FileStorage и DB, а затем открывается база данных и создается кор не вой объ ект. Корневым объектом является постоянно хранимый словарь, в котором сохраняются другие объекты. Объект класса FileStorage отображает базу данных в плоский файл. Имеются также интерфейсы к другим типам хранилищ, таким как хранилища на основе реляционной базы данных.

Добавление объектов в базу данных ZODB выполняется так же просто, как при использовании модуля shelve. Поддерживаются почти любые объекты Python, включая кортежи, списки, словари, экземпляры классов и их комбинации. Как при использовании модуля shelve, чтобы сделать объект постоянно хранимым, достаточно просто присвоить его по ключу корневому объекту базы данных:

>  >> object1 = (1, ‘spam’, 4, ‘YOU’)

>  >> object2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

>  >> object3 = {‘name’: [‘Bob’, ‘Doe’],

‘age’: 42,

‘job’: (‘dev’, ‘mgr’)}

>  >> root[‘mystr’] = ‘spam’ * 3

>  >> root[‘mytuple’] = object1

>  >> root[‘mylist’] = object2

>>> root[‘mydict’] = object3

>>> root[‘mylist’]

[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

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

>>> import transaction

>>> transaction.commit()

>>> storage.close()

\PP4E\Dbase\Zodb-2.x> dir /B c:\temp\mydb*

mydb.fs

mydb.fs.index

mydb.fs.tmp

Без заключительного подтверждения в этом сеансе ни одно из изменений не сохранилось бы. Именно такое поведение чаще всего бывает желательным — если программа завершится аварийно в середине процедуры, выполняющей изменения, уже выполненные к этому моменту частичные изменения не сохранятся. Фактически ZODB поддерживает обычную для баз данных операцию отмены.

Извлечение хранимых объектов из базы данных ZODB в другом сеансе или программе выполняется так же просто: нужно открыть базу данных, как было показано выше, и обратиться по индексам к корневому объекту, чтобы извлечь объекты в память. Подобно хранилищам, создаваемым модулем shelve, корневой объект базы данных поддерживает интерфейс словарей — к нему можно обращаться с указанием индексов, использовать методы словарей, определять количество записей и так далее:

\PP4E\Dbase\Zodb-2.x> python

>   >> from ZODB import FileStorage, DB

>   >> storage = FileStorage.FileStorage(r’C:\temp\mydb.fs’)

>   >> db = DB(storage)

>   >> connection = db.open()

>   >> root = connection.root() # соединиться

>   >> len(root), root.keys() # размер, индекс

(4 [‘mylist’, ‘mystr’, ‘mytuple’, ‘mydict’])

>   >> root[‘mylist’] # извлечь объекты

[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

>>> root[‘mydict’]

{‘job’: (‘dev’, ‘mgr’), ‘age’: 42, ‘name’: [‘Bob’, ‘Doe’]}

>   >> root[‘mydict’][‘name’][-1] # Фамилия Боба

‘Doe’

Так как корневой объект базы данных выглядит как словарь, с ним можно работать как с обычным словарем, например выполнить итерации по списку ключей, чтобы обойти все записи:

>   >> for key in root.keys():

print(‘%s => %s’ % (key.ljust(10), root[key]))

mylist => [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

mystr => spamspamspam

mytuple => (1, ‘spam’, 4, ‘YOU’)

mydict => {‘job’: (‘dev’, ‘mgr’), ‘age’: 42, ‘name’: [‘Bob’, ‘Doe’]}

Кроме того, подобно модулям pickle и shelve ZODB поддерживает возможность сохранения и извлечения экземпляров классов, правда при этом они должны наследовать суперкласс Persistent, реализующий необходимый протокол и перехватывающий операции изменения атрибутов, чтобы обеспечить автоматическое сохранение их на диск:

from persistent import Persistent class Person(Persistent):

def __init__(self, name, job=None, rate=0):

self.name = name self.job = job self.rate = rate def changeRate(self, newrate): self.rate = newrate # автоматически обновит базу данных

При изменении экземпляров классов, хранимых в ZODB, операции изменения атрибутов в памяти приводят к автоматическому сохранению изменений в базе данных. Другие типы операций изменения, такие как добавление элементов в список и присваивание словарям по ключу, все еще требуют повторно выполнять присваивание по оригинальному ключу корневому объекту, чтобы обеспечить принудительное сохранение изменений на диск (встроенные словари и списки не знают, что они являются постоянно хранимыми).

Поскольку пока еще не вышла версия ZODB для Python 3.X, это все, что можно сказать об этой базе данных в этой книге. За дополнительной информацией обращайтесь к ресурсам Интернета, посвященным проектам ZODB и Zope, а также ознакомьтесь с ресурсами в пакете с примерами, о которых говорилось выше. А теперь посмотрим, какие инструменты доступны программам на языке Python для работы с совершенно иной разновидностью баз данных — с реляционными базами данных и SQL.

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий