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()
posted @ 2021-05-07 20:14  silencio。  阅读(67)  评论(0)    收藏  举报