====== MongoEngine ======
It's a MongoDB ORM for Python.
===== First steps =====
==== Installation and import ====
$ pip install mongoengine
To start using MongoEngine we will import like this:
import mongoengine
==== Connecting to a DB ====
To connect a DB we will use the ''connect'' function, its first argument is the DB:
connect('project1')
connect('project1', host='192.168.1.35', port=12345)
connect('project1', username='webapp', password='pwd123')
connect('project1', host='mongodb://localhost/database_name')
===== Defining the schema =====
==== In a nutshell ====
Next schema implements a Blog where a User can create different type Posts. Those types are inherited classes from Post.
class User(Document):
email = StringField(required=True)
first_name = StringField(max_length=50)
last_name = StringField(max_length=50)
class Post(Document):
title = StringField(max_length=120, required=True)
author = ReferenceField(User)
meta = {'allow_inheritance': True}
class TextPost(Post):
content = StringField()
class ImagePost(Post):
image_path = StringField()
class LinkPost(Post):
link_url = StringField()
=== Other field objects ===
* ''tags = ListField(StringField(max_length=30))'', a ''ListField'' is a field object that allows to have a list of other field objects (including other lists).
* ''date_modified = DateTimeField(default=datetime.datetime.now)''
More about this subject in: [[http://docs.mongoengine.org/guide/defining-documents.html#fields]]
==== Storing an object ====
Comment.objects.create(text='Me gusta!')
==== Storing an object inside another ====
class Comment(EmbeddedDocument):
content = StringField()
name = StringField(max_length=120)
class Post(Document):
title = StringField(max_length=120, required=True)
author = ReferenceField(User)
tags = ListField(StringField(max_length=30))
comments = ListField(EmbeddedDocumentField(Comment))
We also could use ''GenericReferenceField'' to reference any kind of document:
class Bookmark(Document):
bookmark_object = GenericReferenceField()
==== Cascade delete ====
When we define a ''ReferenceField'' we can indicate ''reverse_delete_rule=CASCADE'' to delete all the objects when a referenced object is deleted (it does not work with MapFields neither DictFields).
class Post(Document):
title = StringField(max_length=120, required=True)
author = ReferenceField(User, reverse_delete_rule=CASCADE)
tags = ListField(StringField(max_length=30))
comments = ListField(EmbeddedDocumentField(Comment))
Other constans we can pass:
* ''mongoengine.DO_NOTHING''
* ''mongoengine.DENY''
* ''mongoengine.NULLIFY''
* ''mongoengine.CASCADE''
* ''mongoengine.PULL''
==== Dynamic documents ====
DynamicDocument documents work like Document but any data or attributes set to them will also be saved (fields cannot start with _ ).
from mongoengine import *
class Page(DynamicDocument):
title = StringField(max_length=200, required=True)
# Create a new page and add tags
page = Page(title='Using MongoEngine')
page.tags = ['mongodb', 'mongoengine']
page.save()
==== Defining constraints ====
We can specify field uniqueness with ''unique=True'' and multi-fielduniqueness with ''unique_with'' (for a field name, or a list, or a tuple):
class User(Document):
username = StringField(unique=True)
first_name = StringField()
last_name = StringField(unique_with='first_name')
===== Editing Data =====
==== Adding documents ====
ross = User(email='ross@example.com', first_name='Ross', last_name='Lawley').save()
# this is other way to save ross
ross1 = User(email='ross1@example.com')
ross1.first_name = 'Ross1'
ross1.last_name = 'Lawley'
ross1.save()
post1 = TextPost(title='Fun with MongoEngine', author=john)
post1.content = 'Took a look at MongoEngine today, looks pretty cool.'
post1.tags = ['mongodb', 'mongoengine']
post1.save()
post2 = LinkPost(title='MongoEngine Documentation', author=ross)
post2.link_url = 'http://docs.mongoengine.com/'
post2.tags = ['mongoengine']
post2.save()
===== Accessing data =====
A ''Document'' object is actually a ''QuerySet'' object. It lazily queries the database when you need the data. ''QuerySet'' objects perform searches on the data base using functions like...
* ''first()'' to retrieve the first object that matches with the provided query.
* ''count()'' to know the number of objects that matche with the provided query.
==== Examples ====
=== Retrieving all the post titles ===
for post in Post.objects:
print post.title
=== Retrieving a concrete type content ===
for post in TextPost.objects:
print post.content
=== Searching by tag ===
for post in Post.objects(tags='mongodb'):
print post.title
===== Others =====
==== Django support ====
=== Connecting ===
You only need to call ''connect()'' somewhere in the settings module.
If you were not using another Database backend you may need to add a dummy database:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.dummy'
}
}
=== Users ===
Django authentication classes are included as Document classes so they are compatible. To enable them you should add the following to your settings.py file:
AUTHENTICATION_BACKENDS = (
'mongoengine.django.auth.MongoEngineBackend',
)
Remember to call ''set_password()'' method in ''User'' class when assign a password value:
instance.set_password(attrs.get('password', instance.password))