概述
MongoEngine 是一个用于操作 MongoDB 的 Python ODM(Object-Document Mapper),它提供了类似 Django ORM 的接口,使得在 Python 中操作 MongoDB 变得更加简单和直观。
核心概念
- Document: 对应 MongoDB 中的一个集合(Collection),类似于关系型数据库中的表
- EmbeddedDocument: 嵌入文档,用于定义嵌套在 Document 中的子文档结构
- Field: 字段类型,定义文档中每个字段的数据类型和约束
数据库连接
在使用模型之前,需要先建立与 MongoDB 的连接。连接配置如下:
from mongoengine import connect
import conf.config as cf
connect(
cf.MONGODB_NAME,
host=cf.MONGODB_HOST,
port=cf.MONGODB_PORT,
username=cf.MONGODB_USER,
password=cf.MONGODB_PWD,
maxPoolSize=50
)
连接参数说明
cf.MONGODB_NAME: 数据库名称host: MongoDB 服务器地址port: MongoDB 服务器端口username: 认证用户名password: 认证密码maxPoolSize: 连接池最大连接数
字段类型
MongoEngine 提供了多种字段类型,常用的包括:
基础字段类型
| 字段类型 | 说明 | 示例 |
|---|---|---|
StringField |
字符串字段 | name = StringField(max_length=128) |
IntField |
整数字段 | age = IntField(default=0) |
DateTimeField |
日期时间字段 | create_time = DateTimeField(default=datetime.datetime.now) |
ListField |
列表字段 | task_id = ListField() |
DictField |
字典字段 | conf = DictField() |
字段常用参数
max_length: 最大长度(主要用于 StringField)default: 默认值required: 是否必填(默认为 False)unique: 是否唯一(默认为 False)index: 是否创建索引(默认为 False)
示例
# 字符串字段,带最大长度和默认值
status = StringField(max_length=20, default='run')
# 整数字段,带默认值
alarm_option = IntField(default=0)
# 日期时间字段,带默认值
date_creation = DateTimeField(default=datetime.datetime.now())
# 列表字段,带默认值
trans_rate = ListField(default=[])
# 字典字段
conf = DictField()
# 唯一字段
channel_id = StringField(max_length=128, unique=True)
# 带索引的字段
submit_id = StringField(max_length=36, index=True)
Document 文档类
Document 类用于定义 MongoDB 集合的结构。每个 Document 类对应一个集合。
基本结构
from mongoengine import Document, StringField, IntField, DateTimeField
import datetime
class MyDocument(Document):
name = StringField(max_length=128)
age = IntField(default=0)
create_time = DateTimeField(default=datetime.datetime.now)
meta = {
'collection': 'my_collection',
'strict': False
}
EmbeddedDocument 嵌入文档
EmbeddedDocument 用于定义嵌套在 Document 中的子文档结构,类似于关系型数据库中的关联表,但在 MongoDB 中作为嵌入文档存储。
基本结构
from mongoengine import EmbeddedDocument, StringField
class MyEmbeddedDocument(EmbeddedDocument):
field1 = StringField()
field2 = StringField()
在 Document 中使用 EmbeddedDocument
使用 EmbeddedDocumentListField 来定义嵌入文档列表:
class TestModel(Document):
# 使用 EmbeddedDocumentListField 存储嵌入文档列表
info = EmbeddedDocumentListField(EmbLiveDeviceChan, default=[])
Meta 配置
每个 Document 类都应该定义一个 meta 字典,用于配置集合的相关属性。
常用 Meta 选项
collection: 指定集合名称(如果不指定,默认使用类名的小写形式)strict: 是否严格模式True: 严格模式,只允许保存定义的字段False: 非严格模式,允许保存未定义的字段(推荐)
最佳实践
1. 字段命名规范
- 使用有意义的字段名
- 遵循 Python 命名规范(小写字母和下划线)
- 对于日期时间字段,使用统一的命名(如
date_creation,date_updation,create_time,update_time)
2. 默认值设置
- 为常用字段设置合理的默认值
- 日期时间字段使用
datetime.datetime.now作为默认值 - 列表和字典字段使用空列表或空字典作为默认值
3. 字段长度限制
- 为字符串字段设置合理的
max_length,避免存储过长的数据 - 根据业务需求设置合适的长度限制
4. 唯一性约束
- 对于需要唯一性的字段(如 ID、用户名等),使用
unique=True - 注意:唯一性约束会在数据库层面创建唯一索引
5. 索引优化
- 对于经常用于查询的字段,使用
index=True创建索引 - 对于唯一字段,
unique=True会自动创建索引
6. 使用非严格模式
- 推荐使用
strict=False,允许存储未定义的字段,提高灵活性 - 这对于需要存储动态字段的场景特别有用
meta = {
'collection': 'test',
'strict': False
}
7. 嵌入文档的使用
- 对于一对多的关系,如果子文档不会单独查询,使用
EmbeddedDocumentListField - 嵌入文档可以包含自定义方法(如
__str__)
8. 集合命名
- 使用
meta['collection']明确指定集合名称 - 集合名称使用小写字母和下划线
- 保持与业务逻辑相关的命名
总结
通过 MongoEngine,我们可以用面向对象的方式定义 MongoDB 数据模型,这使得代码更加清晰、易于维护。关键要点包括:
- 连接配置:在模型文件顶部建立数据库连接
- 字段定义:根据业务需求选择合适的字段类型和参数
- 文档结构:使用 Document 定义集合,使用 EmbeddedDocument 定义嵌入文档
- Meta 配置:通过 meta 字典配置集合属性
- 最佳实践:遵循命名规范、设置默认值、合理使用索引等
通过遵循这些规范和最佳实践,可以建立清晰、高效、易维护的 MongoDB 数据模型。