1. Mapping documents to Python objects: couchbase_mapping.mapping¶
Mapping from raw JSON data structures to Python objects and vice versa.
>>> from couchbase import Couchbase
>>> server = Couchbase('localhost', 'Administrator', 'password')
>>> db = server.create('python-tests')
To define a document mapping, you declare a Python class inherited from Document, and add any number of Field attributes:
>>> from datetime import datetime
>>> from couchbase_mapping import Document, TextField, IntegerField, DateTimeField
>>> class Person(Document):
... name = TextField()
... age = IntegerField()
... added = DateTimeField(default=datetime.now)
>>> person = Person(name='John Doe', age=42)
>>> person.store(db)
Person(...)
>>> person.age
42
You can then load the data from the Couchbase server through your Document subclass, and conveniently access all attributes:
>>> person = Person.load(db, person.id)
>>> person.name
u'John Doe'
>>> person.age
42
>>> person.added
datetime.datetime(...)
To update a document, simply set the attributes, and then call the store() method:
>>> person.name = 'John R. Doe'
>>> person.store(db)
Person(...)
If you retrieve the document from the server again, you should be getting the updated data:
>>> person = Person.load(db, person.id)
>>> person.name
u'John R. Doe'
>>> server.delete('python-tests')
1.1. Differences from couchdb.mapping¶
- Methods that take a Database object in CouchDB take a couchbase.Bucket object instead.
- Document#store() method takes optional arguments expiration and flags.
- Document.view() method returns a list of Document objects instead of a View document.
- Document.query() method is not supported.
- All views are written in JavaScript. Python view server is not supported.
- Document revisions are not supported.
1.2. Field types¶
- class couchbase_mapping.mapping.TextField(name=None, default=None)¶
Mapping field for string values.
- class couchbase_mapping.mapping.FloatField(name=None, default=None)¶
Mapping field for float values.
- class couchbase_mapping.mapping.IntegerField(name=None, default=None)¶
Mapping field for integer values.
- class couchbase_mapping.mapping.LongField(name=None, default=None)¶
Mapping field for long integer values.
- class couchbase_mapping.mapping.BooleanField(name=None, default=None)¶
Mapping field for boolean values.
- class couchbase_mapping.mapping.DecimalField(name=None, default=None)¶
Mapping field for decimal values.
- class couchbase_mapping.mapping.DateField(name=None, default=None)¶
Mapping field for storing dates.
>>> field = DateField() >>> field._to_python('2007-04-01') datetime.date(2007, 4, 1) >>> field._to_json(date(2007, 4, 1)) '2007-04-01' >>> field._to_json(datetime(2007, 4, 1, 15, 30)) '2007-04-01'
- class couchbase_mapping.mapping.DateTimeField(name=None, default=None)¶
Mapping field for storing date/time values.
>>> field = DateTimeField() >>> field._to_python('2007-04-01T15:30:00Z') datetime.datetime(2007, 4, 1, 15, 30) >>> field._to_json(datetime(2007, 4, 1, 15, 30, 0, 9876)) '2007-04-01T15:30:00Z' >>> field._to_json(date(2007, 4, 1)) '2007-04-01T00:00:00Z'
- class couchbase_mapping.mapping.DictField(mapping=None, name=None, default=None)¶
Field type for nested dictionaries.
>>> from couchbase import Couchbase >>> server = Couchbase('localhost', 'Administrator', 'password') >>> db = server.create('python-tests')
>>> class Post(Document): ... title = TextField() ... content = TextField() ... author = DictField(Mapping.build( ... name = TextField(), ... email = TextField() ... )) ... extra = DictField()
>>> post = Post( ... title='Foo bar', ... author=dict(name='John Doe', ... email='john@doe.com'), ... extra=dict(foo='bar'), ... ) >>> post.store(db) Post(...) >>> post = Post.load(db, post.id) >>> post.author.name u'John Doe' >>> post.author.email u'john@doe.com' >>> post.extra {u'foo': u'bar'}
>>> server.delete('python-tests')
- class couchbase_mapping.mapping.ListField(field, name=None, default=None)¶
Field type for sequences of other fields.
>>> from couchbase import Couchbase >>> server = Couchbase('localhost', 'Administrator', 'password') >>> db = server.create('python-tests')
>>> class Post(Document): ... title = TextField() ... content = TextField() ... pubdate = DateTimeField(default=datetime.now) ... comments = ListField(DictField(Mapping.build( ... author = TextField(), ... content = TextField(), ... time = DateTimeField() ... )))
>>> post = Post(title='Foo bar') >>> post.comments.append(author='myself', content='Bla bla', ... time=datetime.now()) >>> len(post.comments) 1 >>> post.store(db) Post(...) >>> post = Post.load(db, post.id) >>> comment = post.comments[0] >>> comment['author'] u'myself' >>> comment['content'] u'Bla bla' >>> comment['time'] u'...T...Z'
>>> server.delete('python-tests')
- class couchbase_mapping.mapping.ViewField(design, map_fun, reduce_fun=None, name=None, wrapper=<object object at 0x330bae0>, **defaults)¶
Descriptor that can be used to bind a view definition to a property of a Document class.
>>> class Person(Document): ... name = TextField() ... age = IntegerField() ... by_name = ViewField('people', '''\ ... function(doc) { ... emit(doc.name, doc); ... }''') >>> Person.by_name <ViewDefinition '_design/people/_view/by_name'>
>>> print Person.by_name.map_fun function(doc) { emit(doc.name, doc); }
Now the view property can be used as a function that will execute the view.
>>> Person.by_name(db, limit=3) [Person(...), Person(...), Person(...)]
The results produced by the view are automatically wrapped in the Document subclass the descriptor is bound to. In this example, it would return instances of the Person class. But please note that this requires the values of the view results to be dictionaries that can be mapped to the mapping defined by the containing Document class. Alternatively, the include_docs query option can be used to inline the actual documents in the view results, which will then be used instead of the values.