A MongoEngine document class has one or more attributes. Each attribute is an object of Field class. BaseField is the base class or all field types. The BaseField class constructor has the following arguments −
BaseField(db_field, required, default, unique, primary_key)
The db_field represents name of database field.
The required parameter decides whether value for this field is required, default is false.
The default parameter contains default value of this field
The unique parameter is false by default. Set to true if you want this field to have unique value for each document.
The primary_key parameter defaults to false. True makes this field primary key.
There are a number of Field classes derived from BaseField.
Numeric Fields
IntField (32bit integer), LongField (64 bit integer), FloatField (floating point number) field constructors have min_value and max_value parameters.
There is also DecimalField class. Value of this field’s object is a float whose precision can be specified. Following arguments are defined for DecimalField class −
DecimalField(min_value, max_value, force_string, precision, rounding)
min_value | specifies minimum acceptable value |
max_value | specifies maximum value the field can have |
force_string | If True, value of this field is stored as a string |
precision | limits the floating representation to number of digits |
rounding | Number is rounded as per following predefined constants decimal.ROUND_CEILING (towards Infinity) decimal.ROUND_DOWN (towards zero) decimal.ROUND_FLOOR (towards -Infinity) decimal.ROUND_HALF_DOWN (to nearest with ties going towards zero) decimal.ROUND_HALF_EVEN (to nearest with ties going to nearest even integer) decimal.ROUND_HALF_UP (to nearest with ties going away from zero) decimal.ROUND_UP (away from zero) decimal.ROUND_05UP (away from zero if last digit after rounding towards zero would have been 0 or 5; otherwise towards zero) |
Text Fields
StringField object can store any Unicode value. You can specify min_length and max_length of the string in the constructor. URLField object is a StringField with capability to validate input as a URL. EmailField validates the string as a valid email representation.
StringField(max-length, min_length)
URLField(url_regex)
EmailField(domain_whiltelist, allow_utf8_user, allow_ip_domain)
The domain_whitelist argument contains list of invalid domains which you would not support. If set to True, allow_utf8_user parameter allows the string to contain UTF8 characters as a part of email. The allow_ip_domain parameter is false by default, but if true, it can be a valid IPV4 or IPV6 address.
Following example uses numeric and string fields −
from mongoengine import connect
from mongoengine import StringField, IntField, Document, DecimalField
connect('mydata', host='mongodb://localhost/mydata')
class Books(Document):
book_id = IntField(unique=True, required=True)
book_name = StringField(max_length=50)
book_price = DecimalField()
meta = {'allow_inheritance': True}
def _init__(self, book_id, book_name, book_price):
self.book_id = book_id
self.book_name = book_name
self.book_price = book_price
b1 = Books(book_id=1011, book_name='Operating System', book_price=2450)
b1.save()
When above code is executed, the employees collection shows a document as below −
{
"_id":{"$oid":"60349ebb4757ad01ab4288fc"},
"_cls":"Books",
"book_id":1011,
"book_name":"Operating System",
"book_price":2450
}
ListField
This type of field wraps any standard field, thus allowing multiple objects to be used as a list object in a database. This field can be used with ReferenceField to implement one to many relationships.
The student document class from above example is modified as below −
from mongoengine import connect
from mongoengine import StringField, IntField, Document, DecimalField, ListField
connect('mydata', host='mongodb://localhost/mydata')
class Books(Document):
book_id = IntField(unique=True, required=True)
book_name = StringField(max_length=50)
book_price = DecimalField()
topics = ListField(StringField())
def _init__(self, book_id, book_name, book_price):
self.book_id = book_id
self.book_name = book_name
self.book_price = book_price
Books.objects(book_name="Mathematics").update_one(push__topics='Number theory')
b1 = Books(book_id="1013", book_name="maths", book_price=672, topics=[
'Algebra', 'Calculus', 'Statistics', 'Arithematic'])
b1.save()
The document added is shown in JSON format as follows −
{
"_id":{"$oid":"6034a64d3350e4814ce49d60"},
"book_id":1013,
"book_name":"Mathematics",
"book_price":772,
"topics":["Algebra","Calculus","Statistics","Arithematic","Number theory"]
}
DictField
An object of DictField class stores a Python dictionary object. In the corresponding database field as well, this will be stored.
In place of ListField in the above example, we change its type to DictField.
from mongoengine import connect
from mongoengine import StringField, IntField, Document, EmailField, DecimalField
from mongoengine.fields import DictField, ListField
connect('mydata', host='mongodb://localhost/mydata')
class Employees(Document):
employeeCode = IntField()
first_name = StringField(max_length=50)
last_name = StringField(max_length=50)
email = EmailField(required=True, unique=True)
sallary = DecimalField(precision=2)
clients = ListField(StringField())
clientIds = DictField()
def _init__(self, emloyeeCode, fname, lname, email, sallary, clients, clientIds):
self.employeeCode = emloyeeCode
self.first_name = fname
self.last_name = lname
self.email = email
self.sallary = sallary
self.clients = clients
self.clientIds = clientIds
e1 = Employees(employeeCode=1088, first_name='William',
last_name='Patterson', email='wpatterson@classicmodelcars.com', sallary=20300.5678, clients=['Mami', 'Castillo', 'Jones'], clientIds={'Mami': '001', 'Castillo': '002', 'Jones': '003'})
e1.save()
Document in the database appears as follows −
{"_id":{"$oid":"60337a2e492af91b8278be59"},"employeeCode":1088,"first_name":"William","last_name":"Patterson","email":"wpatterson@classicmodelcars.com","sallary":20300.57,"clients":["Mami","Castillo","Jones"],"clientIds":{"Mami":"001","Castillo":"002","Jones":"003"}}
ReferenceField
A MongoDB document can store reference to another document using this type of field. This way, we can implement join as in RDBMS. A ReferenceField constructor uses name of other document class as parameter.
class doc1(Document):
field1=StringField()
class doc2(Document):
field1=StringField()
field2=ReferenceField(doc1)
In following example, StudentDB database contains two document classes, student and teacher. Document of Student class contains reference to an object of teacher class.
from enum import unique
from mongoengine import connect
from mongoengine import StringField, IntField, Document, EmailField, DecimalField
from mongoengine.fields import DictField, ListField, ReferenceField
connect('mydata', host='mongodb://localhost/mydata')
class Employees(Document):
employeeCode = IntField()
first_name = StringField(max_length=50)
last_name = StringField(max_length=50)
email = EmailField(required=True, unique=True)
sallary = DecimalField(precision=2)
def _init__(self, emloyeeCode, fname, lname, email, sallary):
self.employeeCode = emloyeeCode
self.first_name = fname
self.last_name = lname
self.email = email
self.sallary = sallary
class Client(Document):
client_id = IntField(required=True, unique=True)
client_name = StringField()
employeeCode = ReferenceField(Employees)
def _init__(self, client_id, client_name):
self.client_id = client_id
self.client_name = client_name
e1 = Employees(employeeCode=1056, first_name='Mary',
last_name='Patterson', email='mpatterso@classicmodelcars.com', sallary=20400.8678)
e1.save()
c1 = Client(client_id=2345, client_name="Jullie Firrelii", employeeCode=e1)
c1.save()
Run above code and verify result in Compass GUI. Two collections corresponding to two document classes are created in StudentDB database.
The teacher document added is as follows −
{"_id":{"$oid":"60337d98ef1f456786d0ac93"},"employeeCode":1056,"first_name":"Mary","last_name":"Patterson","email":"mpatterso@classicmodelcars.com","sallary":20400.87}
The student document shows the contents as below −
{"_id":{"$oid":"60337d98ef1f456786d0ac94"},"client_id":2345,"client_name":"Jullie Firrelii","employeeCode":{"$oid":"60337d98ef1f456786d0ac93"}}
Note that ReferenceField in Clients document stores _id of corresponding Empoyee document. When accessed, Client object is automatically turned into a reference, and dereferenced when corresponding Employee object is accessed.
To add reference to document being defined, use ‘self’ instead of other document class as argument to ReferenceField. It may be noted that use of ReferenceField may cause poor performance as far retrieval of documents is concerned.
The ReferenceField constructor also has one optional argument as reverse_delete_rule. Its value determines what to be done if the referred document is deleted.
The possible values are as follows −
- DO_NOTHING (0) - don’t do anything (default).
- NULLIFY (1) - Updates the reference to null.
- CASCADE (2) - Deletes the documents associated with the reference.
- DENY (3) - Prevent the deletion of the reference object.
- PULL (4) - Pull the reference from a ListField of references
You can implement one to many relationship using list of references. Assuming that a client document has to be related with one or more employee documents, the Clients must have a ListField of ReferenceField instances.from enum import unique from mongoengine import connect from mongoengine import StringField, IntField, Document, EmailField, DecimalField from mongoengine.fields import DictField, ListField, ReferenceField connect('mydata', host='mongodb://localhost/mydata') class Employees(Document): employeeCode = IntField() first_name = StringField(max_length=50) last_name = StringField(max_length=50) email = EmailField(required=True, unique=True) sallary = DecimalField(precision=2) def _init__(self, emloyeeCode, fname, lname, email, sallary): self.employeeCode = emloyeeCode self.first_name = fname self.last_name = lname self.email = email self.sallary = sallary class Client(Document): client_id = IntField(required=True, unique=True) client_name = StringField() employeeCode = ListField(ReferenceField(Employees)) def _init__(self, client_id, client_name): self.client_id = client_id self.client_name = client_name e1 = Employees(employeeCode=1056, first_name='Mary', last_name='Patterson', email='mpatterso@email.com', sallary=20400.8678) e1.save() e2 = Employees(employeeCode=1088, first_name='William', last_name='Patterson', email='wpason@email.com', sallary=20500.8678) e2.save() c1 = Client(client_id=2345, client_name="Jullie Firrelii", employeeCode=[e1, e2]) c1.save()
On verifying result of the above code in Compass, you will find the client document having reference of two employee documents −
Employee Collection {"_id":{"$oid":"603380f3bc0950f878d35a74"},"employeeCode":1056,"first_name":"Mary","last_name":"Patterson","email":"mpatterso@email.com","sallary":20400.87} {"_id":{"$oid":"603380f3bc0950f878d35a75"},"employeeCode":1088,"first_name":"William","last_name":"Patterson","email":"wpason@email.com","sallary":20500.87} client collection {"_id":{"$oid":"603380f4bc0950f878d35a76"},"client_id":2345,"client_name":"Jullie Firrelii","employeeCode":[{"$oid":"603380f3bc0950f878d35a74"},{"$oid":"603380f3bc0950f878d35a75"}]}
DateTimeField
An instance of DateTimeField class allows data in date format in MongoDB database. MongoEngine looks for Python-DateUtil library for parsing data in appropriate date format. If it is not available in current installation, date is represented using built-in time module’s time.strptime() function. Default value of field of this type is current datetime instance.
DynamicField
Different and varying type of data can be handled by this field. This type of field is internally used by DynamicDocument class.
ImageField
This type of field corresponds to field in document that can store an image file. Constructor of this class can accept size and thumbnail_size parameters (both in terms of pixel size).