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