Mongoengine 简明教程
MongoEngine - Fields
一个 MongoEngine 文档类具有一个或多个属性。每个属性都是 Field 类的对象。BaseField 是所有字段类型的基类。BaseField 类构造函数具有以下参数−
BaseField(db_field, required, default, unique, primary_key)
db_field 表示数据库字段的名称。
required 参数决定该字段的值是否必需,默认为 false。
default 参数包含该字段的默认值
unique 参数默认值为 false。如果要使该字段对每个文档具有唯一值,则将其设置为 true。
primary_key 参数默认为 false。True 使该字段成为主键。
从 BaseField 派生了许多 Field 类。
Numeric Fields
IntField (32 位整数)、 LongField (64 位整数)、FloatField(浮点数)字段构造函数具有 min_value 和 max_value 参数。
还有 DecimalField 类。该字段对象的 value 是一个可以指定其精度的小数。为 DecimalField 类定义了以下参数:
DecimalField(min_value, max_value, force_string, precision, rounding)
min_value |
specifies minimum acceptable value |
max_value |
指定字段可以具有的最大值 |
force_string |
如果为 True,则该字段的值将存储为字符串 |
precision |
将浮点表示限制为数字位数 |
rounding |
数字按照以下预定义常量进行舍入 decimal.ROUND_CEILING(向无穷大)decimal.ROUND_DOWN(向零)decimal.ROUND_FLOOR(向 - 无穷大)decimal.ROUND_HALF_DOWN(到最接近,舍入后为零)decimal.ROUND_HALF_EVEN(到最接近,舍入后为最接近的偶数)decimal.ROUND_HALF_UP(到最接近,舍入后远离零)decimal.ROUND_UP(远离零)decimal.ROUND_05UP(远离零,如果向零舍入后的最后一位数字为 0 或 5;否则向零) |
Text Fields
StringField 对象可以存储任何 Unicode 值。可以在构造函数中指定字符串的 min_length 和 max_length。 URLField 对象是 StringField,能够将输入验证为 URL。 EmailField 将字符串验证为有效的电子邮件表示形式。
StringField(max-length, min_length)
URLField(url_regex)
EmailField(domain_whiltelist, allow_utf8_user, allow_ip_domain)
domain_whitelist 参数包含您不支持的无效域列表。如果设置为 True,allow_utf8_user 参数允许字符串包含 UTF8 字符作为电子邮件的一部分。allow_ip_domain 参数默认为 false,但如果为 true,则它可以是有效的 IPV4 或 IPV6 地址。
以下示例使用数字和字符串字段:
from mongoengine import *
connect('studentDB')
class Student(Document):
studentid = StringField(required=True)
name = StringField()
age=IntField(min_value=6, max-value=20)
percent=DecimalField(precision=2)
email=EmailField()
s1=Student()
s1.studentid='001'
s1.name='Mohan Lal'
s1.age=20
s1.percent=75
s1.email='mohanlal@gmail.com'
s1.save()
当执行上述代码时,student 集合将显示如下所示的文档:
ListField
这种类型的字段会包装任何标准字段,从而允许将多个对象用作数据库中的列表对象。该字段可以与 ReferenceField 一起使用来实现一对多关系。
来自上述示例的学生文档类被修改为如下所示:
from mongoengine import *
connect('studentDB')
class Student(Document):
studentid = StringField(required=True)
name = StringField(max_length=50)
subjects = ListField(StringField())
s1=Student()
s1.studentid='A001'
s1.name='Mohan Lal'
s1.subjects=['phy', 'che', 'maths']
s1.save()
添加的文档以 JSON 格式显示,如下所示:
{
"_id":{"$oid":"5ea6a1f4d8d48409f9640319"},
"studentid":"A001",
"name":"Mohan Lal",
"subjects":["phy","che","maths"]
}
DictField
DictField 类的一个对象存储一个 Python 字典对象。在相应的数据库字段里,它也将被存储。
在上述范例中,将 ListField 类型改为 DictField 类型。
from mongoengine import *
connect('studentDB')
class Student(Document):
studentid = StringField(required=True)
name = StringField(max_length=50)
subjects = DictField()
s1=Student()
s1.studentid='A001'
s1.name='Mohan Lal'
s1.subjects['phy']=60
s1.subjects['che']=70
s1.subjects['maths']=80
s1.save()
数据库中的文档表现如下−
{
"_id":{"$oid":"5ea6cfbe1788374c81ccaacb"},
"studentid":"A001",
"name":"Mohan Lal",
"subjects":{"phy":{"$numberInt":"60"},
"che":{"$numberInt":"70"},
"maths":{"$numberInt":"80"}
}
}
ReferenceField
MongoDB 文档可以使用这种类型的字段存储对另一个文档的引用。借此,我们可以实现与 RDBMS 中的联接。ReferenceField 构造函数使用其他文档类的名称作为参数。
class doc1(Document):
field1=StringField()
class doc2(Document):
field1=StringField()
field2=ReferenceField(doc1)
在下面的范例中,StudentDB 数据库包含两个文档类,即 student 和 teacher。Student 类的文档包含对 teacher 类的对象的引用。
from mongoengine import *
connect('studentDB')
class Teacher (Document):
tid=StringField(required=True)
name=StringField()
class Student(Document):
sid = StringField(required=True)
name = StringField()
tid=ReferenceField(Teacher)
t1=Teacher()
t1.tid='T1'
t1.name='Murthy'
t1.save()
s1=Student()
s1.sid='S1'
s1.name='Mohan'
s1.tid=t1
s1.save()
运行上述代码,并在 Compass GUI 中确认结果。StudentDB 数据库中创建了两个与两个文档类相对应的集合。
添加的 teacher 文档如下:
{
"_id":{"$oid":"5ead627463976ea5159f3081"},
"tid":"T1",
"name":"Murthy"
}
student 文档的内容显示如下:
{
"_id":{"$oid":"5ead627463976ea5159f3082"},
"sid":"S1",
"name":"Mohan",
"tid":{"$oid":"5ead627463976ea5159f3081"}
}
请注意,Student 文档中的 ReferenceField 存储了相应 Teacher 文档的 _id。访问时,Student 对象会自动转换为一个引用,并且在访问相应的 Teacher 对象时取消引用。
如需向正在定义的文档添加引用,请使用 'self' 而不是其他文档类作为引用字段的参数。请注意,使用引用字段在获取文档方面可能会导致性能不佳。
ReferenceField 构造函数还具有一个可选参数 reverse_delete_rule。它的值决定了在引用的文档被删除时要执行的操作。
可能的值如下:
-
DO_NOTHING (0) - 什么也不做(默认)。
-
NULLIFY (1) - 将引用更新为 null。
-
CASCADE (2) - 删除与引用关联的文档。
-
DENY (3) - 阻止删除引用对象。
-
PULL (4) - 从引用列表字段中提取引用
可以使用引用列表来实现一对多的关系。假设一个 student 文档不得不与一个或多个 teacher 文档关联,那么 Student 类必须具有 ReferenceField 实例的 ListField。
from mongoengine import *
connect('studentDB')
class Teacher (Document):
tid=StringField(required=True)
name=StringField()
class Student(Document):
sid = StringField(required=True)
name = StringField()
tid=ListField(ReferenceField(Teacher))
t1=Teacher()
t1.tid='T1'
t1.name='Murthy'
t1.save()
t2=Teacher()
t2.tid='T2'
t2.name='Saxena'
t2.save()
s1=Student()
s1.sid='S1'
s1.name='Mohan'
s1.tid=[t1,t2]
s1.save()
在 Compass 中确认上述代码的结果时,您会发现 student 文档具有两个 teacher 文档的引用:
Teacher Collection
{
"_id":{"$oid":"5eaebcb61ae527e0db6d15e4"},
"tid":"T1","name":"Murthy"
}
{
"_id":{"$oid":"5eaebcb61ae527e0db6d15e5"},
"tid":"T2","name":"Saxena"
}
Student collection
{
"_id":{"$oid":"5eaebcb61ae527e0db6d15e6"},
"sid":"S1","name":"Mohan",
"tid":[{"$oid":"5eaebcb61ae527e0db6d15e4"},{"$oid":"5eaebcb61ae527e0db6d15e5"}]
}