This repository has been archived by the owner on Jul 14, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 132
/
version_migration.txt
139 lines (102 loc) · 5.56 KB
/
version_migration.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
=========================
Migration from 0.4 to 0.5
=========================
The version 0.5 not only changes the API but brings a lot of bug fix so,
you may really want to upgrade.
Presentation
------------
One of the main feature of MongoDB is speed. Why using MongoDB if libraries on
top of it are slow ? I created MongoKit to be as simple and faster as possible.
It appears that collection are really important and are used all the time when
we tend to use them dynamically. And using dynamic collections with MongoKit
was a pain : there was too much code to write and many bugs underlying.
I noticed that I was using a lot the pymongo library in my code when I wanted
dynamic collection or quickly fetching raw data. So, I decided to follow the
pymongo api for MongoKit.
Pymongo use the following scheme : `connection.database.collection`. Let's say
we have created many ``Doc`` object in a collection "migration" on the db "test":
>>> from pymongo import Connection
>>> con = Connection()
>>> data = con.test.migration.find()
>>> type(data.next()) is dict
True
The issue here is that we get raw data.
Let's create our ``Doc`` object so it look like this::
>>> from mongokit import Document
>>> class Doc(Document):
... structure = {'title':unicode}
The `db_name` and `collection_name` are not hard explained in the object
declaration anymore. We just describe the validation schema. Then, we have
to fire a connection and register our ``Doc`` object ::
>>> from mongokit import Connection
>>> con = Connection()
>>> con.register([Doc])
Let's the BlogPost object seen in the introduction:
>>> con.register([BlogPost])
>>> blogpost = con.test.migration.BlogPost()
>>> blogpost['title'] = u'my title'
>>> blogpost['body'] = u'a body'
>>> blogpost['author'] = u'me'
>>> blogpost.save()
Note that this is quite the same as the current api. We just get the BlogPost object
via the collection. The main advantage of this approach is that we don't have to
bother about the collection.
You can simulate the current api behavior like this:
class BlogPostDocument(Document): # <-- just rename the class by adding "Document"
...
>>> con.register([BlogPostDocument]) # register the document
>>> BlogPost = con.test.migration.BlogPostDocument()
>>> blogpost = BlogPost()
>>> blogpost2 = BlogPost()
Another advantage is the ability of using the collection dynamically without pain.
Let's say that we want to put all BlogPost into a user collection (so one collection
by user) :
>>> user_col = 'me'
>>> blogpost = con.test[user_col].BlogPost()
Quering is as simple as instanciating object. There's two way of fetching objects :
* getting raw data (the pymongo's way)
* getting instanciated object with all method defined (the mongokit way)
The first approach will produce only python dict and is very fast.
The second will wrap the data into the MongoDocument. This is useful if we defined
methods and want to use them.
Getting raw data :
>>> raw_data = con.test.migration.find()
Actually, all pymongo's method can be apply :
>>> con.test.migration.remove({})
>>> con.test.drop_collection('migration')
Getting instanciated objects :
>>> blogpost_cursor = con.test.migration.BlogPost.find()
>>> bp = blogpost_cursor.next()
We can apply MongoDocument methods (`validate`, `to_json` etc...)
>>> bp.validate()
>>> bp
{'body': u'a body', 'title': u'my title', 'date_creation': datetime.datetime(...), 'rank': 0, 'author': u'me'}
Other mongokit queries are available :
>>> blogpost_cursor = con.test.migration.BlogPost.fetch() # get only BlogPost
So, what changed ?
------------------
* replace `MongoDocument` by `Document`. I changed the name in order to facilitate the migration. So there won't be surprises
* uuid is False by default in the `save()` method (instead of True)
* replaced `all()` by `find()`. This in order to keep consistancy with the pymongo driver
* replace `one()` by `find_one().
* remove `db_name` and `collection_name`. Instead, you have to register your object to the connection.
* passing a dictionary in "fields" is now deprecated. The problem when passing a dictionary is that a dictionary is unordered. This might be a problem for compound keys. If you want to make compound keys indexes, you now need to pass a list of tuples::
>>> from mongokit import *
>>> class MyDoc(Document):
... structure = {
... 'standard':unicode,
... 'other':{
... 'deep':unicode,
... },
... 'notindexed':unicode,
... }
...
... indexes = [
... {
... 'fields':[('standard',INDEX_ASCENDING), ('other.deep',INDEX_DESCENDING)],
... 'unique':True,
... },
... ]
* removed cascade (`belong_to`) and related features. MongoKit is writed to be fast and production ready. Adding such feature brings bugs and complication in maintainability. As far as I know, those features was not really used and there are easy to implemented. So, I removed them. This bring more less and cleaner code. If you don't know how to implement those features, send me a message on the mailing list, Bitbucket or Twitter and I'll write a tutorial.
* dropped Mongodb auth support. I'm not happy with the way it was handled. I have to think on a better API. So, in order to avoid another API changed, I removed this feature. If you really need this feature, contact me so we can think a new API together.
* last but not least : better integration with web framework. All that you have to do is to set a connection and register all your objects.