一、ODM的选择和安装
1.1、MongoDB中的ODM
MongoEngine
- 使用最为广泛的ODM
- http://mongoengine.org/
uMongo
- 支持sync/async特性的ODM
- https://umongo.readthedocs.io/en/latest/
1.2、MongoEngine的安装
- MongoDB版本支持情况:v3.4、v3.6、v4.0
- python版本支持情况:python3.6+
- 安装:
pip install mongoengine
1.3、连接到MongoDB
-
方式一,使用默认配置:
connect('students')
-
方式二,指定主机地址和端口
# 连接方式1 connect('students', host='*', port=27017) # 连接方式2 connect('students', host='mongodb://localhost/students')
连接到多个数据库
- 建立连接
connect(alias='db1', db='test') connect(alias='db2', db='test-temp')
- 断开连接:
disconnect(alias='db1')
二、MongoEngine模型介绍
2.1、ODM模型
示例代码
from mongoengine import Document
class User(Document):
email = StringField(required=True)
first_name = StringField(max_length=50)
last_name = StringField(max_length=50)
2.2、常见数据类型
2.3、数据类型通用参数
- db_field:文档中的field/域/列名称
- required:是否为必填项
- default:默认值
- unique:唯一性约束
- choices:可选择的列表
- primary_key:是否为文档的主键,默认为False
2.4、类属性meta常见配置项
-
类属性,其配置项为python的dict(字典)
-
示例代码
class User(Document): username = StringField() meta = { }
常见配置项
- db_alias:指定文档所在的数据库(逻辑库)
- collection:指定文档所在的集合
- ordering:指定文档的默认排序规则
- indexes:指定文档的索引规则
2.5、文档的嵌套模型
学生信息数据字典
文档的嵌套场景
-
情况一,数组-简单数据类型:
{'grades': [76, 51, 84]}
模型解决方案
from mongoengine import ListField, IntField, Document class Student(Document): grades = ListField(IntField())
-
情况二,数组-文档:
{'grades': [{'score': 76}, {'score': 51}]}
from mongoengine import Document, EmbeddedDocument, EmbeddedDocumentField,IntField,ListField # 自定义类型 class CourseGrade(EmbeddedDocument): score = IntField() class Student(Document): grades = ListField(EmbeddedDocumentField(CourseGrade))
-
情况三,单个文档:
{'grade': {'course_name': '语文', 'score': 76}}
from mongoengine import ( Document, EmbeddedDocument, EmbeddedDocumentField, IntField, StringField ) # 自定义类型 class CourseGrade(EmbeddedDocument): course_name = StringField() score = IntField() class Student(Document): grades = EmbeddedDocumentField(CourseGrade)
示例
from enum import Enum
from mongoengine import (
Document, connect, StringField,
EnumField, IntField, EmbeddedDocument,
EmbeddedDocumentField, ListField
)
# 连接到test数据库
connect('test', host='localhost', port=27017)
class SexEnum(Enum):
MAN = '男'
WOMEN = '女'
class CourseGrade(EmbeddedDocument):
"""成绩信息(科目、老师、成绩)-被嵌套的文档"""
course_name = StringField(max_length=64, required=True, verbose_name='科目')
teacher = StringField(max_length=16, verbose_name='老师')
score = IntField(min_value=0, max_value=150