Package: pymongo-document-modeling
pymongo-document-modelingCreate data model backed with pymongo called: Document which have
ability of polymorphism, and inheritance.FeatureThis document modeling library designed with OOP as a goal. Therefore it
can associate field, and inherit it to its subclasses.InstallationBegin with installation>pipinstallpymongo-document-modelingConfigurationOnce you have installedpymongo-document-modelingmodule. Now you
can start configure your pymongo. To state the configuration file, first prepare your config.Here is a dirty example of configuration file.[default]connection_string=mongodb://localhost:27017/database_name=test_beds[test_data_pool]connection_string=mongodb://localhost:27017/database_name=test_data_poolFor more advance cases. You can actually specify many connection sections as you want
(Butdefaultsection is required).Now let the system know where your configuration file is. To do this, callconf.update_config()before your declare your first class.frompymongo_documentimportconf# example a - specify the fileconf.update_config('conf/my-config.ini')# read config from os.path.getcwd() + 'conf/my-config.ini'# example b - specify directory (default config file name will be assumed).conf.update_config('conf/')# read config from os.path.getcwd() + 'conf/pymongo-connectors.ini'Lastly, within your model, you can reference this connector name. If omitteddefaultwill be used.
(See first example in Quick start section’sMetaclass).NoteIfconf.update_config()never get invoked, this default configuration will be assumed.[default]connection_string=mongodb://localhost:27017/database_name=default_databaseQuick StartLearn by example is simplest, and fastest. Here are some quick and dirty
simple class examples.frompymongo_documentimportdocumentsasdoc# Import library module as "doc"classSimpleDocument(doc.Doc):int_val=doc.FieldNumeric()str_val=doc.FieldString(default="default_value_of_string")classMeta:collection_name="simple_document"# Special class to annotate the document name to be saved.connection_name="test_data_pool"# Explicitly state connection_name, (If omitted, 'default' will be used)Load and Save is as simple as Django’s Model.d=SimpleDocument()d.int_val=500d.save()# document is saved to your mongodbloaded=SimpleDocument(d.object_id)printd.int_val# 500printd.str_Val# default_value_of_stringprintd.object_id# auto generated bson.ObjectIdFor more complex classes, you can inherit from existing class, override
existing fields.classABitComplexDocument(SimpleDocument):# Extend existing modelint_val_2=doc.FieldNumeric(none=False)# Add new fieldstr_val=doc.FieldString(default="default_value_changed")# Override existing model's fieldclassMeta:collection_name=":complex_1"# use ':' to annotate the system to let this data model shared parent's collectionMongo doesn’t have join, but we could establish connection between
collection. We facilitate this by nesting them in a list of documents.classHolderOfSimpleDocuments(doc.Doc):list_of_docs=doc.FieldList(doc.FieldDoc(SimpleDocument))classMeta:collection_name="document_holders"There are many more type of example, please see the complete list of
documentation below.ReferencesDocument ObjectDocument is designed withdjangomodel in mind. With help of specialMetaclass, we can beautifully annotate the document withindices,connection_name,collection_nameand more.To create a new document, you can simply start by extendingDocclass.frompymongo_documentimportdocumentsasdocclassMySimpleDoc(doc.Doc):# Define fields herename=doc.FieldString(max_length=30,none=False)classMeta:collection_name='my_simple_doc'With this code,MySimpleDocwill be created when this module is
imported. ThisMySimpleDocwill have exactly 2 fields (not 1).Fieldnameis created as a string field, cannot beNone, and
text length must not exceeds 30.Fieldobject_idis also (automatically) created by inherit it
fromdoc.Docclass. You can explicitly override this field, by
redeclare the field with exact same name. The type can be totally
different.o=MySimpleDoc()# Create a new MySimpleDoc instanceo.save()# Error thrown, 'name' is required.o.name=1# Error thrown, in correct type, 'basestring' is required.o.name='peatiscoding'# Set nameo.save()# Successfully saved to collection 'my_simple_doc'Document.managerAll documents class will be equipped withmanagerobject (pymongo_document.Docsclass).manageris just likeobjectsin Django’s Model’s manager. Allows user tofind,update,
ordeletedocuments.Find APITo make things easy, I’ve decided to use pymongo existingfindapi. For complete doc
seefind() document. pymongo collection’sfind()method normally returndictas output.
Instead of returning simpledict, theDocumentinstance will be returned.o=MySimpleDoc()o.save()cursor=MySimpleDoc.manager.find().sort('_id')# use Cursor's method as pymongo did.foraincursor:print"%s"%a.object_id# cursor returned objects is now already inflated as Document.FieldSpecAware ObjectDocclass is inherited fromFieldSpecAwareclass.FieldSpecAwaretaken care
ofFielddetection, and overseer them in translating from python object, to document
(saving format for mongodb).Normally you will useFieldSpecAwarewithFieldNested. So that you can define a
dict within another document. See @FieldNested for more information.FieldsEvery field are customisable via the use of**kwargsof which each options will be provided in the
sample per each individual fields below.In addition, every field is compatible with assigning its ownvalidatoras well. To add your own
validators. Create a field, then specific validators keyword argument in field creation.Validator can be defined in 2 styles.Callable- if you supplied validators as a simple callable, then you are responsible to raise a properFieldValidationErrormanually.(Callable, basestring)- ifcallablereturns True,basestringwill be raised as an Error message.Here is an example.defin_the_past_or_throw(value,name):ifisinstance(value,datetime)andvalue<datetime.now():returnraiseerr.FieldValidationError(value,'Value must be past',name)classTestMeDocument(doc.Doc):positive_number=doc.FieldNumeric(validators=[(lambdav:v<0,'positive number is required')])even_number=doc.FieldNumeric(validators=[(lambdav:v%2==1,'even number only')])negative_odd_number=doc.FieldNumeric(validators=[(lambdav:v>0,'negative number is required'),(lambdav:v%2==0,'odd number is required')])custom_value=doc.FieldDateTime(validators=[in_the_past_or_throw])# Callable styleBy assigning incorrect valueFieldValidationErrorwill be raised.FieldObjectIdUse this field to store anyObjectId. But If you would like to store
another document reference. TryFieldDocorFieldAnyDocinstead.UsageclassSimpleDocument(doc.Doc):oid=doc.FieldObjectId()ObjectId field acceptsbson.ObjectIdinstance, orbson.ObjectIdcompatible string (24 alphanumeric string).Notethat normally if you inherit fromDocyou will automatically
getobject_idfield for free.FieldNumericUse this field to store any numeric numbers.UsageclassSimpleDocument(doc.Doc):VALUE_A=1VALUE_B=2VALUE_C=3VALUES=((VALUE_A,'1st value'),(VALUE_B,'2nd value'),(VALUE_C,'3rd value'))amount1=doc.FieldNumeric(default=3,max_value=50,min_value=10)amount2=doc.FieldNumeric(max_value=40,none=False)amount3=doc.FieldNumeric()# no max, no min, can be None, no defaultamount4=doc.FieldNumeric(choices=VALUES)max_value- (numeric) set upper bound of field. Default is None (no upper bound).min_value- (numeric) set lower bound of field. Default is None (no lower bound).default- (numeric) set a default value for this field. Default is None.none- (boolean) set to False to prohibit None value for this field. Default is True.choices- (tuple, list) set possible values for the field. Default is None.FieldStringUse this file to store anybasestringinstance.UsageclassSimpleDocument(doc.Doc):VALUE_A='A'VALUE_B='B'VALUE_C='C'VAULES=((VALUE_A,'A description'),(VALUE_B,'B description'),(VALUE_C,'C description'),)str_value=doc.FieldNumeric(default="default_string",max_length=10)fixed_length_str_value=doc.FieldString(fixed_length=2)fixed_choices_str_value=doc.FieldString(choices=VALUES,default=VALUE_A)fixed_pattern_str_value=doc.FieldString(pattern=r'[a-z]{2}\d{5}3-[A-Z]{2}')pattern- (SRE_Pattern|regex pattern string) set a required pattern for input string. Default is None.max_length- (numeric) set maximum character count. Default is None (no upper bound).fix_length- (numeric) set constant character count. Default is None (no upper bound).default- (numeric) set a default value for this field. Default is None.none- (boolean) set to False to prohibit None value for this field. Default is True.choices- (tuple, list) set possible values for the field. Default is None.FieldDictUse this field to store complete any python dict without schema.UsageclassSimpleDocument(doc.Doc):data=doc.FieldDict()default- (dict) set a default value for this field. Default is None.none- (boolean) set to False to prohibit None value for this field. Default is True.FieldTupleUse this field to store a FieldSpec value that obligated by each rule based on position on the list.UsageclassTupleFieldDocument(doc.Doc):data=doc.FieldTuple(doc.FieldNumeric(),doc.FieldString(),doc.FieldNumeric())default- (tuple) set a default value for this field. Default is None.none- (boolean) set to False to prohibit Nont value for this field. Default is True.UnlikeFieldList,FieldTupleconstructor accept*argsas argument ofFieldSpec. EachFieldSpeccorrespond to Field specification for each element on the tuple respectively.ThereforeFieldTupleassignment required an exact tuple size to theFieldSpecprovided in constructor.o=TupleFieldDocument()o.data=(12,'test',12)# this is okayo.data=(12,'test')# raise doc.FieldValidationError invalid tuple sizeo.data=('test',24,45)# raise doc.FieldValidationError index 1 should be integer, index 2 should be text