1
2
3
4
5
6 """ Schema is an easy way to map couchdb object in pythoin object. It's
7 similar to ORMs but with all couchdb glory.
8
9 An application describes the kinds of data it uses with a Document object. A
10 document is a Python class that inherits from the `couchdbkit.schema.Document`
11 class. The document class defines a new kind of CouchDB document and the
12 properties the kind is expected to take.
13
14 Document properties are defined using class attributes on the document class.
15 Each class attribute is an instance of a subclass of the Property class,
16 usually one of the provided property classes. A property instance holds
17 configuration for the property, such as whether or not the property is required
18 for the instance to be valid, or a default value to use for the instance if
19 none is provided.
20
21
22 from couchdbkit import Document
23
24 class Pet(Document):
25 name = schema.StringProperty(required=True)
26 type = schema.StringProperty(required=True)
27 birthdate = schema.DateProperty()
28 weight_in_pounds = schema.IntegerProperty()
29 spayed_or_neutered = schema.BooleanProperty()
30 owner = schema.StringProperty()
31
32 An CouchDB document is represented in the API by an instance of the
33 corresponding document class. The application can create a new document by
34 calling the constructor of the class. The application accesses and manipulates
35 properties of the entity using attributes of the instance. The document
36 instance constructor accepts initial values for properties as keyword
37 arguments.
38
39
40 pet = Pet(name="Fluffy",
41 type="cat",
42 owner="Jean")
43 pet.weight_in_pounds = 24
44
45
46 Document is dynamic
47 --------------------
48
49 Sometimes it is usefull to have different properties on each document. CouchDB
50 allows it, so why not having it in python. A document can have both dynamic and
51 static property. Any value assigned to an attribute of an instance of a
52 document becomes a property of the CouchDB document, using the name of the
53 attribute. These properties are known as dynamic properties. Properties defined
54 using Property class instances in class attributes are fixed properties.
55
56
57 class Person(Document):
58 first_name = schema.StringProperty()
59 last_name = schema.StringProperty()
60 hobbies = schema.ListProperty()
61
62 p = Person(first_name="Albert", last_name="Johnson")
63 p.hobbies = ["chess", "travel"]
64
65 p.chess_elo_rating = 1350
66
67 p.travel_countries_visited = ["Spain", "Italy", "USA", "Brazil"]
68 p.travel_trip_count = 13
69
70 Because dynamic properties do not have document property definitions, dynamic
71 properties are not validated. Any dynamic property can have a value of any of
72 the python types, including None.
73
74 Unlike fixed properties, dynamic properties need not exist. A dynamic property
75 with a value of None is different from a non-existent dynamic property. You
76 can delete a dynamic property by deleting the attribute.
77
78 del p.chess_elo_rating
79
80 A request that uses a dynamic property will only return entities whose value
81 for the property is of the same type as the value used in the request.
82 Similarly, the request will only return entities with that property set.
83
84
85 p1 = Person()
86 p1.favorite = 42
87 db.save_doc(p1)
88
89 p2 = Person()
90 p2.favorite = "blue"
91 db.save_doc(p2)
92
93 p3 = Person()
94 db.save_doc(p3)
95
96 people = Person.view(db, "person/favorite", startkey=0, endkey=50)
97 # people has p1, but not p2 or p3
98
99 people = Person.view(db, "person/favorite")", startkey=50)
100 # people has no results
101
102
103 Some dynamic data in couchdb are automatically converted to their python type.
104 Those are datetime, datetime.date, datetime.time and Decimal types. this is
105 only possible if date/time fields are :rfc:`8601` strings in the couchdb
106 document.
107
108 Document inheritance in simplecouchdb work almost identically to the way normal
109 class inheritance works in Python.
110
111 class Animal(Document)
112 name = StringProperty(required=True)
113 type = StringProperty(required=True)
114
115 class Pet(Animal):
116 birthdate = DateProperty()
117 weight_in_pounds = IntegerProperty()
118 spayed_or_neutered = BooleanProperty()
119 owner = StringProperty()
120
121 The `Pet` document will have 6 properties name, type, birthdate,
122 weight_in_pounds, spayed_or_neutered, owner. It can be used as a common
123 Document object. Pet and Animal have 2 different doc_type.
124
125 For now, there is no way in CouchDB to know that Pet inherit from Animal.
126 Though this feature will be implemented soon.
127
128
129 Properties and Types
130 --------------------
131
132 Couchdb supports all Javascript types, including Unicode strings, integers,
133 floating point numbers. We also added support for dates and decimal types. Each
134 of the CouchDB value type has a corresponding Property class provided by the
135 :mod:`simplecouchdb.schema` module.
136
137
138 Other way to save on the db.
139 ----------------------------
140
141 If you don't want to use the db object to save doc each time and save
142 àla "ORM" you can fix a db to a Document class::
143
144 class A(Dcoument):
145 s = StringProperty()
146
147 A.set_db(db)
148
149 a = A()
150 a.save()
151
152 This method isn't really threadsafe since once class will share a db
153 reference across threads, changing a db to a class will be applied to
154 all threads. It's better to use the db object methods if you want to be
155 threadsafe.
156
157 """
158
159 from .properties import *
160 from .base import *
161 from .properties_proxy import *
162
164 """ associate a db to multiple `Document` class"""
165 for doc in docs:
166 if hasattr(doc, '_db'):
167 doc._db = db
168