Skip to content

Commit

Permalink
Update README.rst
Browse files Browse the repository at this point in the history
  • Loading branch information
zzzsochi committed Nov 7, 2017
1 parent ccc0d7f commit 3926810
Showing 1 changed file with 171 additions and 22 deletions.
193 changes: 171 additions & 22 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Full documentation: http://yadm.readthedocs.org
Requirements
------------

YAMD support MongoDB version 3.x only. MongoDB 2.x is not supported.
YADM support MongoDB version 3.x only. MongoDB 2.x is not supported.

Minimal version of python is 3.4.

Expand All @@ -27,61 +27,210 @@ Minimal version of python is 3.4.
Quick start
-----------

Create the models
=================

.. code:: python
import pymongo
from yadm import Database, Document, fields
from yadm import Database
from yadm import Document, EmbeddedDocument
from yadm import fields
from yadm.serialize import to_mongo
class User(Document):
__collection__ = 'users'
name = fields.StringField()
email = fields.EmailField()
class PostLogItem(EmbeddedDocument):
op = fields.StringField(choices=['created', 'comment_added'])
at = fields.DatetimeField()
data = fields.MongoMapField()
# Create model
class BlogPost(Document):
__collection__ = 'blog_posts'
class Post(Document):
__collection__ = 'posts'
user = fields.ReferenceField(User)
title = fields.StringField()
body = fields.StringField()
log = fields.ListField(fields.EmbeddedDocumentField(PostLogItem))
class Comment(Document):
__collection__ = 'comments'
user = fields.ReferenceField(User)
created_at = fields.DatetimeField(auto_now=True)
post = fields.ReferenceField(Post)
text = fields.StringField()
All documents creates from class ``Document``. You can use multiple inheritance.

``__collection__`` magic attribute setups the collection name for documents of model.


Connect to database
===================

.. code:: python
client = pymongo.MongoClient('mongodb://localhost:27017')
db = Database(client, 'blog')
``Database`` object is a wrapper about ``pymongo`` or ``motor`` ``Database``.


Create documents
================

User
----

# Create post
post = BlogPost()
.. code:: python
user = User(name='Bill', email='hero_of@the.galaxy')
db.insert(user)
Just insert document to database.


Post
----

.. code:: python
post = Post()
post.user = user
post.title = 'Small post'
post.body = 'Bla-bla-bla...'
post.log = [PostLogItem(op='created', at=datetime.utcnow())] # first log item
db.insert(post)
# Connect to database
client = pymongo.MongoClient('localhost', 27017)
db = Database(client, 'test')
You can fill documents as below.

# Insert post to database
db.insert(post)

# Query posts
qs = db(BlogPost).find({'title': {'$regex': '^S'}})
Comment the post
----------------

.. code:: python
comment = Comment()
comment.user = user
comment.post = post
comment.text = "RE: Bla-bla-bla..."
db.insert(comment)
db.update_one(post, push={
'log': to_mongo(PostLogItem(op='comment_added',
at=comment.created_at,
data={
'comment': comment.id,
'user': comment.user.id,
}))
})
We add log item to post's log. This is very usefull case.


Queries
=======

find
----

.. code:: python
qs = db(Post).find({'title': {'$regex': '^S'}})
assert qs.count() > 0
1. ``db(Post)`` creates the ``QuerySet`` object;
2. ``find`` method get the raw-query and return new ``QuerySet`` object with updated criteria;
3. ``count`` method make the query to database and return value.

.. code:: python
for post in qs:
assert post.title.startswith('S')
# Query one post
post = db(BlogPost).find_one({'title': 'Small post'})
``__iter__`` method make the ``find``-query and returns the generator of documents.


# Change post
post.title = 'Bla-bla-bla title'
find_one
--------

.. code:: python
# Save changed post
db.save(post)
post = db(Post).find_one({'user': user.id})
``find_one`` get the first finded document.

.. code:: python
user = post.user
Get attribute with reference makes the query to referred collection. Warning: N+1 problem!
We have a cache in ``QuerySet`` object and get one referred document only once for one queryset.


join
----

Yes! We have a joins! In userspace...

.. code:: python
comments = db(Comment).find({'post': post.id}).sort(('created_at', 1))
for comment in comments.join('user'):
print(comment.user.name, comment.text)
1. Create the queryset for comments;
2. In ``join`` we get all documents for qs, get all users with one ``$in``-query and bind to documents.


aggregations
------------

.. code:: python
agg = (db.aggregate(Comment)
.match(user=user.id})
.group(_id='post', count={'$sum:' 1})
.sort(count=-1))
for item in agg:
print(item)
Is equal of this:

.. code:: python
agg = db.aggregate(Comment, [
{'match': {'user': user.id}},
{'group': {'_id': 'post', 'count': {'$sum:' 1}}},
{'sort': {'count': -1}},
])
for item in agg:
print(item)
=======
CHANGES
=======

1.4.14 (2017-11-06)
------------------
-------------------

* Add ``EnumField`` for save ``enum.Enum``;
* Add ``EnumStateField`` for simple state machines based on ``enum.Enum``.


1.4.13 (2017-10-31)
------------------
-------------------

* Add ``QuerySet.batch_size`` method for setup batch size for cursor;
* Some minor fixes.
Expand Down

0 comments on commit 3926810

Please sign in to comment.