- PVSM.RU - https://www.pvsm.ru -
[1] — документо-ориентированная система управления базами данных (СУБД) с открытым исходным кодом, не требующая описания схемы таблиц. Написана на языке C++ и распространяется в рамках лицензии Creative Commons.
В последнее время становится довольно популярной и восстребованой. И вот возникла идея использовать ее в связке с фреймворком Django. Собственно о чем далее и пойдет речь.
Для решения поставленной задачи мы будем использовать приложение mongodb-engine. Данное приложение тесно связано еще с несколькими приложениями, установкой которых мы и займемся вначале.
Django-nonrel [2] — используется для поддержки NoSQL в Django.
pip install hg+https://bitbucket.org/wkornewald/django-nonrel
djangotoolbox [3] — набор инструментов для работы с нереляционными базами данных, лишним не будет.
pip install hg+https://bitbucket.org/wkornewald/djangotoolbox
А теперь уже ставим и mongodb-engine:
pip install git+https://github.com/django-nonrel/mongodb-engine
Указываем нашу базу данных в settings:
DATABASES = {
'default' : {
'ENGINE' : 'django_mongodb_engine',
'NAME' : 'my_database'
}
}
При необходимости также можно указать host, port, user, password.
Данное приложение предоставляет два типа полей для хранения произвольных данных, не входящих в стандартную django модель.
Списки и им подобные, представление массивов в формате BSON [4]
from djangotoolbox.fields import ListField
class Post(models.Model):
...
tags = ListField()
>>> Post(tags=['django', 'mongodb'], ...).save()
>>> Post.objecs.get(...).tags
['django', 'mongodb']
Вариант с указанием типа:
class Post(models.Model):
...
edited_on = ListField(models.DateTimeField())
>>> post = Post(edited_on=['1010-10-10 10:10:10'])
>>> post.save()
>>> Post.objects.get(...).edited_on
[datetime.datetime([1010, 10, 10, 10, 10, 10])]
Данный тип поля удобно использовать для организации связи один-ко-многим:
from djangotoolbox.fields import EmbeddedModelField, ListField
class Post(models.Model):
...
comments = ListField(EmbeddedModelField('Comment'))
class Comment(models.Model):
...
text = models.TextField()
EmbeddedModelField — используется для организации связей между моделями.
Второй тип поля DictField, который используется в BSON для обьектов.
from djangotoolbox.fields import DictField
class Image(models.Model):
...
exif = DictField()
>>> Image(exif=get_exif_data(...), ...).save()
>>> Image.objects.get(...).exif
{u'camera_model' : 'Spamcams 4242', 'exposure_time' : 0.3, ...}
Вариант с указанием типа:
class Poll(models.Model):
...
votes = DictField(models.IntegerField())
>>> Poll(votes={'bob' : 3.14, 'alice' : '42'}, ...).save()
>>> Poll.objects.get(...).votes
{u'bob' : 3, u'alice' : 42}
Post.objects.filter(...).update(title='Everything is the same')
Можно использовать для обновления оператор $set
.update(..., {'$set': {'title': 'Everything is the same'}})
А также функцию F() [5]
Post.objects.filter(...).update(visits=F('visits')+1)
В результате получится что то такое:
.update(..., {'$inc': {'visits': 1}})
Если Вам не хватает возможностей Django ORM, можно использовать запросы к MongoDB минуя стандартный механизм.
raw_query() — принимает один аргумент, возвращает данные в виде стандартного Django queryset. Что хорошо для дальнейшей обработки данных.
Пример с geo данными, модель:
from djangotoolbox.fields import EmbeddedModelField
from django_mongodb_engine.contrib import MongoDBManager
class Point(models.Model):
latitude = models.FloatField()
longtitude = models.FloatField()
class Place(models.Model):
...
location = EmbeddedModelField(Point)
objects = MongoDBManager()
получим все точки рядом с конкретными координатами:
>>> here = {'latitude' : 42, 'longtitude' : 3.14}
>>> Place.objects.raw_query({'location' : {'$near' : here}})
raw_update() — используется если нам недостаточно стандартных средств для обновления данных.
Модель:
from django_mongodb_engine.contrib import MongoDBManager
class FancyNumbers(models.Model):
foo = models.IntegerField()
objects = MongoDBManager()
использование:
FancyNumbers.objects.raw_update({}, {'$bit' : {'foo' : {'or' : 42}}})
В данном примере выполняется побитовое or для каждого foo в базе.
На этом возможности данной связки не заканчиваются, но если пречислять все, то статья не оправдано затянется. Полное описание и примеры можно будет посмотреть по представленным ниже ссылкам.
Ссылки:
MongoDB [6]
mongodb-engine [7]
Пример создания блога [8]
GitHub [9]
Автор: int22h
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/django-2/21037
Ссылки в тексте:
[1] Image: http://ru.wikipedia.org/wiki/MongoDB
[2] Django-nonrel: http://www.allbuttonspressed.com/projects/django-nonrel
[3] djangotoolbox: http://www.allbuttonspressed.com/projects/djangotoolbox
[4] BSON: http://ru.wikipedia.org/wiki/BSON
[5] F(): https://docs.djangoproject.com/en/dev/topics/db/queries/#filters-can-reference-fields-on-the-model
[6] MongoDB: http://www.mongodb.org/
[7] mongodb-engine: http://django-mongodb.org/
[8] Пример создания блога: http://django-mongodb.org/tutorial.html
[9] GitHub: https://github.com/django-nonrel/mongodb-engine
[10] Источник: http://habrahabr.ru/post/160191/
Нажмите здесь для печати.