Блоґ одного кібера

Історія хвороби контуженого інформаційним вибухом

Вступ до ZODB

with one comment

ZODB – то така старовинна технологія об’єктних баз даних, знайдена десь поряд з антикітерським механізмом, але на відміну від останнього про неї збереглось ще трохи документації, чим можна скористатись. Якщо вам потрібно розібратись в чомусь написаному з допомогою цієї ZODB, то можете витратити 20 хв і прочитати мою публікацію. Вона коротка тому ви нічим не ризикуєте. 🙂

Щоб встановити ZODB, досить написати:

pip install ZODB

Щоб відкрити з’єднання з базою в файлі потрібно виконати:

import ZODB

connection = ZODB.connection('data.db')

Щоб створити базу даних в пам’яті можна замість назви файлу передати None.

Щоб додати об’єкт в базу, треба відкрити базу, і прив’язати наш об’єкт до якогось об’єкта що вже існує в базі. В кожній базі для цього існує кореневий об’єкт, і називається він root:

root = connection.root

Наприклад:

root.db_name = 'test'

Щоправда зміни ще не записані в базу. Щоб їх записати, треба зробити комміт:

import transaction
transaction.commit()

Тепер при наступному відкритті матимемо:

root.db_name
# 'test'

Правда з мутабельними об’єктами така штука вже не проходить:

root.numbers
# [1, 2]
root.numbers.append(3)
root.numbers
# [1, 2, 3]
transaction.commit() 

Якщо цю сесію перевідкрити, отримаємо все ті ж:

root.numbers
# [1, 2]

Для того щоб об’єкт знав що він змінився (хоча атрибут посилається на той самий список), треба перед коммітом спеціально його позначити:

root._p_changed = True
transaction.commit()

Окрім пошуку даних в ієрархії об’єктів та їх атрибутів, можна зберігати дані за ключем. Робиться це за допомогою бінарного дерева:

from BTrees import OOBTree
root.de_uk = OOBTree.BTree()
root.de_uk['Kofferraum'] = 'Багажник'

Цей об’єкт сам слідкує за змінами в собі, тому можна зразу коммітити, і потім отримувати дані:

root.de_uk
# <BTrees.OOBTree.OOBTree object at 0x8f47a04>
print root.de_uk['Kofferraum']
# Багажник

Ну й на останок – як зберігати атрибути підоб’єктів кореневого об’єкта. Просто так:

class Something(object):
     pass
 
root.something = Something()
root.something.a = 1
transaction.commit()

Виходить як завжди невдало:

root.something
<broken __main__.Something instance>

broken __main__.Something означає що воно не змогло знайти код для класу об’єкту в модулі __main__. Потурбуйтесь про те, щоб ваші класи не перейменовувались і не переміщувались, якщо в них є екземпляри записані в базу, це раз. Ну і два – як і зі списками та словниками, атрибути звичайних класів так просто не зберігаються при комміті. Навіть якщо використати _p_changed = True. Треба наслідувати об’єкт від Persistent:

from persistent import Persistent
class Subobject(Persistent):
    pass

root.subobject = Subobject()
root.subobject.a = 2
transaction.commit()

Й це все що я хотів написати про ZODB.

Посилання

Advertisements

Written by bunyk

Липень 21, 2014 at 23:00

Оприлюднено в Кодерство

Tagged with

Одна відповідь

Subscribe to comments with RSS.


Залишити відповідь

Заповніть поля нижче або авторизуйтесь клікнувши по іконці

Лого WordPress.com

Ви коментуєте, використовуючи свій обліковий запис WordPress.com. Log Out / Змінити )

Twitter picture

Ви коментуєте, використовуючи свій обліковий запис Twitter. Log Out / Змінити )

Facebook photo

Ви коментуєте, використовуючи свій обліковий запис Facebook. Log Out / Змінити )

Google+ photo

Ви коментуєте, використовуючи свій обліковий запис Google+. Log Out / Змінити )

З’єднання з %s

%d блогерам подобається це: