Python + CouchDB
Знайшов час і нарешті трохи погрався з однією з NoSQL баз даний CouchDB. Саме ця база з інших зацікавила мене тим, що вона написана на Erlang. Враховуючи що її прибрав до рук Apache певно вірять у велике майбутнє.
Архітектура системи
Подібно іншим документно-орієнтованим СУБД (Mnesia, Lotus Notes, MongoDB), і на відміну від реляційних БД, CouchDB призначена для роботи з напів-структурованою інформацією і має такі особливості:
- Дані зберігаються не в рядках і колонках, а у вигляді JSON-подібних документів, моделлю яких є не таблиці, а дерева;
- Типізація елементів даних, тобто зіставлення окремих полях документів типів INTEGER, DATE тощо, не підтримується – замість цього користувач повинен написати функцію-валідатор;
- Цілісність бази даних забезпечується виключно на рівні окремих записів (але не на рівні зв’язків між ними);
- Зв’язку між таблицями або записами принципово не підтримуються, відповідно операція об’єднання (JOIN) між таблицями не визначена;
- Для побудови індексів і виконання запитів використовуються функції представлення (view);
- Функції-валідатори, функції-подання, функції-фільтри зберігаються в текстовому вигляді в самій базі даних;
- Ці функції, як правило, написані на мовах JavaScript або Erlang, а для їх виконання запускається окремий сервер запитів, взаємодія з яким відбувається за допомогою сокетів і текстового JSON-протоколу;
- Кожній базі даних у системі CouchDB відповідає єдине B-дерево (не плутати з двійковим деревом);
- Кожне B-дерево зберігається у вигляді окремого файлу на диску;
- Одночасно може бути запущено декілька потоків для читання бази даних і лише один – для запису;
- Цілісність бази даних забезпечується тільки при запису даних на диск;
- Подання зберігаються в БД та їх індекси оновлюються безперервно, проте при кожному оновленні функцій подання або відображення оновлюється все B-дерево цілком;
- При обробці даних за допомогою функцій-уявлень використовується спрощена модель технології MapReduce, що дозволяє проводити паралельні обчислення, в тому числі і на багатоядерні процесори;
- Розподіл обчислень на кілька вузлів не підтримується – замість цього використовується механізм реплікації;
- Обробка даних за допомогою ланцюжка послідовних функцій MapReduce не підтримується;
- Підтримується вертикальна масштабованість, що означає підтримку не тільки величезних кластерів, але і портативних пристроїв (нетбуки, смартфони та ін);
- Зовнішній інтерфейс (API) до даної СУБД побудований на основі архітектури REST, тобто сама база даних, окремі записи, відображення і запити – суть ресурси, які мають унікальну адресу (URL) і підтримують операції GET, PUT, POST, DELETE;
- Тому для взаємодії з базою даних було написано так багато клієнтських бібліотек, у тому числі на таких мовах JavaScript, PHP, Ruby, Python і Erlang;
- Взаємодія між окремими компонентами СУБД, тобто з серверами уявлень здійснюється знову ж таки за допомогою текстового протокол HTTP, а дані передаються в форматі JSON; це дозволило використовувати різні мови програмування для написання цих компонентів – Java, Python, JavaScript та ін.
Історія розвитку
Проект CouchDB був прийнятий в інкубатор Apache у лютому 2008 року. Не дивлячись на те, що CouchDB спочатку призначався для роботи в операційній системі Linux, вже розроблено варіанти цієї системи для операційних систем Windows і MacOS. Більш того, дистрибутив Linux Ubuntu 9.10 (Karmic Kola) по-замовчуванням включає CouchDB.
Використання CouchDB
Незважаючи на те, що реліз CouchDB має номер 0.10, вона вже використовується в багатьох програмних продуктах і на безлічі веб-сайтів, в тому числі:
- UbuntuOne, Firefox, TomBoy, Akonadi, Evolution – для синхронізації адрес, заміток і закладок.
- Ajatus – розподілена CRM-система.
- Mozilla Raindrop – агрегатор повідомлень електронної пошти, соціальних мереж, систем обміну миттєвими повідомленнями (Skype, Jabber).
Інтерфейси на Python
По великому рахунку для керування цією базою цілком достатньо urllib2. Але вже є деякі готові обгортгки, які я спробував сам.
CouchDB має чудовий веб-інтерфейс до керування самою базою. Там можна створювати бази, робити вибірки та тестити javascript функції.
couchdb-python має всі корисні абстракції і навіть трохи більше. Це “більше” полягає в можливості поставити схему документа в декларативному Django-like стилі і реалізація пітонячьего view-сервера. Перше потрібно щоб якось структурувати документи і роботу з ними, а друга для того, щоб використовувати python як мову для map/reduce обробників замість штатного JavaScript. Вміє працювати як з simplejson так і з швидкою cjson бібліотекою. Використовує httplib2.
сouchdbkit – вміє практично все теж саме, але має трохи більше хелперів і екстеншенів. Вміє інтегруватись із Django. Тягне за собою в залежності restkit і розумну бібліотеку anyjson для вибору оптимального json пакету в системі. Недоліком є відсутність view-сервера.
couchquery – з усіх найменш відома та найслабша. Має базовий набір для роботи з сouchdb.
42-django-couchdb Це вже надбудова над couchdb-python у вигляді Django-бд бекенда.
couchdb-python
>>> import couchdb
>>> from couchdb.client import Server
>>> from couchdb.schema import Document, TextField, IntegerField
>>>
>>> server = Server('http://localhost:5984/')
>>> server.resource.http.add_credentials('admin', 'pass')
>>> db = server.create('db1')
>>>
>>> class Banner(Document):
... clicks = IntegerField()
... banner = TextField()
...
>>> b = Banner()
>>> b.clicks = 1
>>> b.banner = 'banner1'
>>> b.store(db)
<Banner u'8d97edb044111e1c7be5d1b0b36c5510'@
u'1-7fd3d19dabfbe52d71327711c6c6c3e0'
{u'banner': u'banner1', u'clicks': 1}>
>>> b2 = Banner()
>>> b2.clicks=10
>>> b2.banner = 'banner2'
>>> b2.store(db)
<Banner u'5538aad62da4ba9d1ef18fd0f80991e3'@
u'1-e9ed885d4ad523d485b271e4a695f266'
{u'banner': u'banner2', u'clicks': 10}>
>>> len(db)
2
>>> for id in db:
... ban = Banner.load(db,id)
... print ban.clicks,ban.banner
...
10 banner2
1 banner1
>>> sql = '''function(doc) { if (doc.banner=="banner2"){
emit([doc.banner], doc); }}'''
>>> for i in db.query(sql):
... print i.value.get('clicks'),i.value.get('banner')
...
10 banner2
сouchdbkit
як імплантацію до Django прописуємо settings.py
#settings.py
COUCHDB_DATABASES = (
('engine.banners', 'http://admin:[email protected]:5984/db1'),
)
INSTALLED_APPS = (
...
'couchdbkit.ext.django',
...
)
модель виглядає наступним чином
#models.py
from couchdbkit.ext.django.schema import *
class Banner(Document):
clicks = IntegerProperty()
banner = StringProperty()
з javascript функціями напряму не працює, для початку треба створити view-ху у базі, після чого можна її викликати:
#views.py
from engine.banners.models import Banner
def some_view(request):
b= Banner()
banner = b.view('d1/v1').first()
можна працювати із формами по Django-ORM-у
#forms.py
class BannerForm(DocumentForm):
class Meta:
document = Banner
#views.py
def some_form(request):
if request.POST:
form = BannerForm(request.POST)
if form.is_valid():
form.save()
else:
form = BannerForm()
сouchdbkit непоганий, але ще трохи недопрацьований як на мене.
Цікаво було б почути хто що використовує та зауваження в мою сторону 🙂
Читайте також:
- Cassandra vs MongoDB vs CouchDB vs Redis vs Riak vs HBase comparison
- Erlang CouchDB fault-tolerance
- Django suit admin inline pagination
- Ordering related objects in Django
- MemcachedKeyLengthError: Key length is > 250
- How to expire session on browser close in django
- django-stdimage traceback "The '%s' attribute has no file associated with it"
- django custom admin
- Django yandex and google maps integration
- Fix Django 1.4 admin_site ForeignKeyRawIdWidget issue