MongoEngine
MongoEngine
这里我们是基于flask框架操作mongoengine,所以也有专门的Flask-MongoEngine模块让我们对接mongoengine的安装配置和使用。
MongoEngine:http://docs.mongoengine.org/apireference.html#misc
Flask-MongoEngine:http://docs.mongoengine.org/projects/flask-mongoengine/en/latest/
djangoORM/SQLALChemy ---> pymysql -> mysql
mongoengine --> pymongo -> mongoDB
安装命令
# 安装mongoengine
# pip install mongoengine
# 安装flask-mongoengine
pip install flask-mongoengine
settings/dev.py
,配置信息
# MongoDB的ORM框架-mongoengine
MONGODB_SETTINGS = {
'host': 'mongodb://yingming:yingming@127.0.0.1:27017/yingming',
'db': 'yingming', # 可选参数
}
flask项目初始化集成mongoengine
from flask_mongoengine import MongoEngine
# 实例化mongoengine
mongoengine = MongoEngine()
mongoengine的使用开始于 Document模型基类进行创建的,模型类的声明,例子:
from application import mongoengine as engine
class xxxDocument(engine.Document):
meta = {
'collection': '集合名称', # 设置当前文档类模型操作是mongo里面的哪个集合
'ordering': ['-created_time'], # 字段排序,多个字段使用逗号隔开
'strict': False, # 是否使用严格语法[mongoDB的内部查询语法]
'indexes': [ # 索引列表
'title', # 普通索引
'$title', # 文本索引
'#title', # 哈希索引
('title', '-rating'), # 联合索引
('category', '_cls'),
{ # TTL索引
'fields': ['created_time'],
'expireAfterSeconds': 3600
}
]
}
username = engine.StringField(required=True, validators=[validators.InputRequired(message='username不能为空!')])
password = engine.StringField(min_length=6, max_length=16)
email = engine.EmailField()
sex = engine.IntField(default=1)
money = engine.DecimalField()
website = engine.URLField()
sex = engine.BooleanField(default=True)
info = engine.ReferenceField(Info) # 关联子文档
love = engine.ListField(mgdb.StringField(max_length=30)) # 列表的成员是字符串
content = engine.EmbeddedDocumentField(Content) # 长文本
remark = engine.DictField() # 字典格式
字段类型
字段 | 选项 | 说明 |
---|---|---|
StringField | regex =None 正则表达式 min_length=None 最小长度 max_length=None 最大长度 |
字符串 URLField:url地址 EmailField:邮箱地址 |
IntField | min_value=None 最小值 max_value=None 最大值 |
整型 |
FloatField | min_value=None 最小值 max_value=None 最大值 |
浮点型 |
DecimalField | min_value=None 最小值 max_value=None 最大值 precision=2 默认小数位的精度 rounding='ROUND_HALF_UP' 四舍五入的舍入规则 |
十进制数值型 |
BooleanField | 布尔型 | |
DateTimeField | 日期时间类型 | |
ComplexDateTimeField | separator=',' 分隔符号 | 精确日期时间类型 |
EmbeddedDocumentField | document_type=文档模型类 | 嵌入式文档类型 |
DynamicField | 动态数据类型 | |
ListField | field=None 成员类型 max_length=None 成员最大个数 |
列表类型 |
SortedListField | field=None 成员类型 max_length=None 成员最大个数 |
有序列表类型 |
DictField | field=None 成员类型 | 字典类型 |
MapField | field=None 成员类型 | 映射类型 |
ReferenceField | document_type –将被引用的文档类型 dbref –将引用存储为DBRef 或作为ObjectId。 reverse_delete_rule –确定删除引用对象时的操作 kwargs –传递给父级的关键字参数BaseField |
关联引用类型 |
LazyReferenceField | 同上 | 关联引用类型(懒惰引用) |
BinaryField | max_bytes=None 最大字节长度 | 二进制数据 |
ImageField | size =(width,height,force) 存储图像的最大大小 thumbnail_size=(width,height,force) 生成缩略图的大小 |
图像类型 |
SequenceField | collection_name –计数器集合的名称(默认为“ mongoengine.counters”) sequence_name –集合中序列的名称(默认为“ ClassName.counter”) value_decorator –可以用作计数器的任何对象(默认int) |
自增类型 |
UUIDField | binary=True | UUID类型 |
PointField | 地理空间坐标(经纬度) | |
MultiPointField | 地理空间坐标列表(经纬度) |
字段公共属性/选项
属性名 | 默认值 | 描述 |
---|---|---|
db_field | None | mongodb中存储对应的属性名 |
required | False | 是否必填 |
default | None | 默认值 |
unique | False | 是否唯一 |
unique_with | None | 是否与其他字段组成联合唯一 |
primary_key | False | 是否设置为主键 |
validators | None | 写入数据时的验证规则 |
choices | None | 是否是枚举类型 |
null | False | 是否允许设置为None |
mongoengine提供的文档模型的常用操作,例子:
# 保存数据
# 方式1:
文档模型类.objects.create(字段=xxx, 字段=xxx)
# 方式2:
document = 文档模型类(字段=xxx,字段=xxx)
document.save(validate=False)
# 查询数据 基于QuerySet读取结果
Document.objects.all() # 获取所有数据
Document.objects.filter(条件子句).all() # 按条件过滤获取所有数据
Document.objects.first() # 获取一条数据
Document.objects.filter(条件子句).first() # 按条件过滤获取一条数据
Document.objects.get() # 根据主键获取数据
# 更新数据
# 方式1:
Document.objects.update({"字段":"值","字段":"值",....})
Document.objects.filter(条件子句).update({"字段":"值","字段":"值",....})
# 方式2:
document = Document.objects.get(pk=pk)
document.字段 = 值
document.save(validate=False)
# 删除数据
# 方式1:
Document.objects.filter(条件子句).delete()
# 方式2:
document = Document.objects.get(pk=pk)
document.delete()
# 查询条件写法一样基于filter() 和django一样,字段__运算法名称=值。外键__字段__运算符
# 字段__in = []
# 字段__lte = "值"
# 字段__gte = "值"
documents.py,举例:
from wtforms import validators
import mongoengine as engine
class xxxDocument(engine.Document):
meta = {
'collection': '集合名称', # 设置当前文档类模型操作是mongo里面的哪个集合
'ordering': ['-create_at'], # 字段排序,多个字段使用逗号隔开
'strict': False, # 是否使用严格语法[mongoDB的内部查询语法]
'indexes': [ # 索引列表
'username', # 普通索引
'$title', # 全文搜索文本索引
'#title', # 哈希索引
('title', '-rating'), # 联合索引,此处就是title和category组成联合索引
('category', '_cls'),
{ # TTL索引
'fields': ['created'], # 字段名
'expireAfterSeconds': 3600 # 数据有效期
}
]
}
username = engine.StringField(required=True, validators=[validators.InputRequired(message='username不能为空!')])
password = engine.StringField(min_length=6, max_length=16)
function = engine.EmailField(db_field="def")
sex = engine.BooleanField(default=True)
money = engine.DecimalField()
website = engine.URLField()
info = engine.ReferenceField(Info) # 关联子文档,就是另一个前面声明的mongoengine的文档模型Info
love = engine.ListField(engine.StringField(max_length=30)) # 列表的成员是字符串 List[str]
content = engine.EmbeddedDocumentField(Content) # 长文本
remark = engine.DictField() # 字典格式
orchard/documents.py,代码:
from application import mongoengine as engine
from application.settings import game
class GameConfigDocument(engine.Document):
"""
种植园配置模型
一个Document对应的就是一个集合,叫文档模型类, 主要定义文档中的字段信息和索引信息
Document类的实例对象, 就是mongoDB中的真实数据文档
"""
meta = {
'collection': 'game_config',
'ordering': ['-_id'], # 倒序排列
'strict': False, # 是否严格语法
'indexes': [ # 索引列表
'config_name', # 普通索引[注意:索引的建立可能会和pymongo里面设置的产生冲突]
]
}
config_name = engine.StringField(required=True, unique=True)
init_package_capacity = engine.IntField(required=True)
max_package_capacity = engine.IntField(required=True)
unlock_package = engine.ListField(engine.IntField()) # 列表的成员是整型
unlock_package_item = engine.IntField(required=True)
def __str__(self):
return self.config_name
class UserInfoDocument(engine.Document):
"""
用户登录信息文档模型
"""
meta = {
'collection': 'user_info',
'ordering': ['_id'], # 正序排列
'strict': False, # 是否严格语法
'indexes': [ # 索引列表
'uid', # 普通索引
'sid', # 普通索引
('sid', 'uid'), # 联合索引
]
}
uid = engine.IntField(required=True)
sid = engine.StringField(required=True)
# 用户注册时的初始化背包格子
package_number = engine.IntField(default=game.INIT_PACKAGE_CAPACITY)
orchard/services.py,代码:
from . import documents, serializers
def user_login(uid: str, sid: str) -> Dict:
"""
用户在种植园中的登录处理[绑定用户ID与websocket的会话ID]
:param uid: 用户保存在数据库中id,用于识别用户身份
:param sid: 本次请求过来的websocket客户端的会话ID session_id
:return:
"""
# 判断当前用户是否在mongo中之前就有记录
try:
user_info = documents.UserInfoDocument.objects.get(uid=uid, sid=sid)
except documents.UserInfoDocument.DoesNotExist:
user_info = documents.UserInfoDocument.objects.filter(uid=uid).first()
if user_info is None:
# 添加登录绑定记录
user_info = documents.UserInfoDocument.objects.create(sid=sid, uid=uid)
else:
# 更新sessionID记录
user_info.sid = sid
user_info.save()
uis = serializers.UserInfoSchema()
return uis.dump(user_info)
orchard/serializers.py,代码:
class UserInfoSchema(Schema):
"""用户登录会话绑定记录的构造器"""
uid = fields.UUID()
sid = fields.String()