详解python中mongoengine库用法

目录
  • 一、MongoDB的安装与连接
  • 二、MongoEngine模型介绍
    • 2.1、ODM模型介绍
    • 2.2、常见数据类型
    • 2.3、数据类型通用参数
    • 2.4、类属性meta常见配置项
    • 2.5、文档的嵌套模型
  • 三、添加数据
    • 3.1、方式一
    • 3.2、方式二:使用create()方法
  • 四、查询数据
    • 4.1、单个文档查询
    • 4.2、条件查询
    • 4.3、聚合统计
    • 4.4、排序
    • 4.5、分页处理
  • 五、修改和删除数据
    • 5.1、修改数据
    • 5.2、删除数据

一、MongoDB的安装与连接

安装:pip install mongoengine

连接mongodb数据库

from pymongo import MongoClient
cli = MongoClient('192.168.124.104', 27017)
mongodb = cli['test']
print(mongodb)
from mongoengine import connect
#  连接到User数据库
connect('user', host='192.168.124.104', port=27017)

二、MongoEngine模型介绍

2.1、ODM模型介绍

from mongoengine import Document, StringField
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(字典)

from mongoengine import Document, StringField
class User(Document):
    email = StringField(required=True)
    first_name = StringField(max_length=50)
    last_name = StringField(max_length=50)
    meta = {
    }

常见的配置项:

  • db_alias:指定文档所在的数据库(逻辑库)
  • collection:指定文档所在的集合
  • ordering:指定文档的默认排序规则
  • indexes:指定文档的索引规则

2.5、文档的嵌套模型

学生信息数据字典

文档的嵌套场景

情况一,数组-简单数据类型:{'grades': [76, 51, 84]}

from mongoengine import Document, IntField, ListField
class Student(Document):
    grade = ListField(IntField())

情况二,单个文档:{'grade': {'course_name': '语文', 'score': 76}}

from mongoengine import Document, StringField, IntField, ListField, EmbeddedDocument, EmbeddedDocumentField
#  自定义类型
class CourseGrade(EmbeddedDocument):
    course_name = StringField()
    score = IntField()
class Student(Document):
    grade = EmbeddedDocumentField(CourseGrade)

情况三,数组-文档:{'grades': [{'score': 76}, {'score': 51}]}

from mongoengine import Document, IntField, ListField, EmbeddedDocument, EmbeddedDocumentField
#  自定义类型
class CourseGrade(EmbeddedDocument):
    score = IntField()
class Student(Document):
    grade = ListField(EmbeddedDocumentField(CourseGrade))

完整代码:

from mongoengine import Document, connect, EnumField, StringField, IntField, ListField, EmbeddedDocument, \
    EmbeddedDocumentField
from enum import Enum
#  连接到User数据库
connect('user', host='192.168.124.104', port=27017)
class SexEnum(Enum):
    MAN = '男'
    WOMAN = '女'
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, required=True, verbose_name='成绩')
    def __repr__(self):
        return f"CourseGrade({self.course_name},{self.score})"
    def __str__(self):
        return self.__repr__()
class Student(Document):
    """学生信息"""
    # verbose_name 自定义参数,用于显示定义域的名称
    stu_no = IntField(required=True, unique=True, verbose_name='学号')
    stu_name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性别')
    class_name = StringField(max_length=10, verbose_name='班级')
    address = StringField(max_length=255, verbose_name='家庭住址')
    phone_no = StringField(max_length=11, verbose_name='电话号码')
    age = IntField(min_value=0, max_value=150, verbose_name='年龄')
    grades = ListField(EmbeddedDocumentField(CourseGrade), verbose_name='成绩数组')
    meta = {
        #  指定文档的集合
        'collection': 'students',
        #  指定排序,可以指定多个域。例如:'age':根据年龄升序,'-age':根据年龄降序
        'ordering': ['-age']
    }
    def __repr__(self):
        return f'Grade({self.stu_no}, {self.stu_name})'
    def __str__(self):
        return self.__repr__()
class Grade(Document):
    """学生成绩"""
    # verbose_name 自定义参数,用于显示定义域的名称
    stu_no = IntField(required=True, verbose_name="学号")
    stu_name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性别')
    class_name = StringField(max_length=10, verbose_name='班级')
    address = StringField(max_length=255, verbose_name='家庭住址')
    phone_no = StringField(max_length=11, verbose_name='电话号码')
    age = IntField(min_value=0, max_value=150, verbose_name='年龄')
    grade = EmbeddedDocumentField(CourseGrade, verbose_name='成绩')
    meta = {
        # 指定文档的集合
        'collection': 'grades',
        # 指定排序,可以指定多个域。例如:'age':根据年龄升序,'-age':根据年龄降序
        'ordering': ['-age']
    }
    def __repr__(self):
        return f'Grade({self.stu_no}, {self.stu_name})'
    def __str__(self):
        return self.__repr__()

三、添加数据

添加数据一般有两种方式:

3.1、方式一

一般步骤:

  • 第一步,构造ODM模型类对象:user=User(username='张三')
  • 第二步,验证数据:user.validate()
  • 第三步,保存数据:user.save()

模型中的验

  • 内置的验证器,如max_length, min_value
  • 自定义验证器

模型中自定义验证方法示例代码如下:

import re
from mongoengine import StringField
from mongoengine.errors import ValidationError
def phone_required(value):
    pattern = r'^1[0-9][10]$'
    if not re.search(pattern, value):
        raise ValidationError('请输入正确的手机号')
phone_no = StringField(validation=phone_required)

方式一示例代码:

import random
from model import Student, Grade, SexEnum, CourseGrade
class LearnMongoDBEngine(object):

    def __init__(self, info):
        self.info = info
        print(self.info)

    def add_one_student(self):
        """新增一个学生信息"""
        student = Student(
            stu_no=random.randint(3000, 9999999),
            stu_name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            class_name='六年级三班',
            address=self.info['address'],
            phone_no=self.info['phone'],
            age=random.randint(10, 15),
            grades=[
                CourseGrade(course_name='语文', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='数学', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='英语', teacher=self.info['teacher'], score=random.randint(1, 100)),
            ]
        )
        print(student, student.grades)
        result = student.save()
        return result
if __name__ == '__main__':
    info = {'name': '铁扇公主', 'address': '北京市朝阳区', 'phone': '19121741234', 'teacher': '王老师'}

    obj = LearnMongoDBEngine(info)
    obj.add_one_student()

mongodb数据库中插入的数据:

3.2、方式二:使用create()方法

User.objects.create(**kwargs)

示例代码:

import random
from model import Student, Grade, SexEnum, CourseGrade
class LearnMongoDBEngine(object):
    def __init__(self, info):
        self.info = info
        print(self.info)
    def add_one_student(self):
        """新增一个学生信息"""
        result = Student.objects.create(
            stu_no=random.randint(3000, 9999999),
            stu_name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            class_name='六年级三班',
            address=self.info['address'],
            phone_no=self.info['phone'],
            age=random.randint(10, 15),
            grades=[
                CourseGrade(course_name='语文', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='数学', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='英语', teacher=self.info['teacher'], score=random.randint(1, 100)),
            ]
        )
        # student = Student(
        #     stu_no=random.randint(3000, 9999999),
        #     stu_name=self.info['name'],
        #     sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
        #     class_name='六年级三班',
        #     address=self.info['address'],
        #     phone_no=self.info['phone'],
        #     age=random.randint(10, 15),
        #     grades=[
        #         CourseGrade(course_name='语文', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #         CourseGrade(course_name='数学', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #         CourseGrade(course_name='英语', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #     ]
        # )
        print(result, result.grades)
        # result = student.save()
        return result
if __name__ == '__main__':
    info = {'name': '卢俊义', 'address': '上海市浦东新区', 'phone': '18721741234', 'teacher': '张老师'}
    obj = LearnMongoDBEngine(info)
    obj.add_one_student()

mongodb数据库中插入的数据:

四、查询数据

结果集QuerySet的获取:User.objects,User是模型对象

常用的查询方法:

  • all():查询所有文档
  • filter():按照条件查询
  • count():满足条件的文档数
  • sum()/average():求和/求平均数
  • order_by():排序
  • .skip().limit():分页

4.1、单个文档查询

  • first():没有文档则返回None,User.objects.first()
  • get(**kwargs)

多个文档时,异常:MultipleObjectsReturned
没有文档时,异常:DoesNotExist
仅有一个文档时:返回ODM对象

示例代码:

from model import Student
class LearnMongoDBEngine(object):
    def get_one_student(self):
        """查询一个学生的信息"""
        student_info = Student.objects.first()
        print(student_info, student_info.id, student_info.stu_name, student_info.address)
        return student_info
    def get_all_student(self):
        """查询所有学生的信息"""
        student_all_info = Student.objects.all()
        print(student_all_info)
        return student_all_info
    def get_student_by_id(self, pk: str):
        """根据学生的id查询"""
        student_info_id = Student.objects.get(id=pk)
        print(student_info_id)
        return student_info_id
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.get_one_student()
    obj.get_all_student()
    obj.get_student_by_id('62dcd1f1a0da9e5521e73223')

运行结果:

4.2、条件查询

1)比较运算符

在MongoEngine中使用双下划线(__)分割。比如:age__gt=12,表示年龄大于12的学生信息。

2)MongoEngine中的字符串查询   【i表示不区分大小写】

3)多个条件组合查询

  • Q函数的使用:from mongoengine.queryset.visitor import Q
  • 多个条件同时满足:Student.objects.filter(Q(key1=value1) & Q(key2=value2))
  • 多个条件部分满足:Student.objects.filter(Q(key1=value1) | Q(key2=value2))
from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def get_one_student(self):
        """查询一个学生的信息"""
        student_info = Student.objects.first()
        print(student_info, student_info.id, student_info.stu_name, student_info.address)
        return student_info
    def get_all_student(self):
        """查询所有学生的信息"""
        student_all_info = Student.objects.all()
        print(student_all_info)
        return student_all_info
    def get_student_by_id(self, pk: str):
        """根据学生的id查询"""
        student_info_id = Student.objects.get(id=pk)
        print(student_info_id)
        return student_info_id
    def get_student_1(self):
        """获取大于12岁的学生信息"""
        result = Student.objects.filter(age__gt=12)
        print(result)
        return result
    def get_student_2(self):
        """获取所有姓李的学生"""
        result = Student.objects.filter(stu_name__startswith='李')
        print(result)
        return result
    def get_student_3(self):
        """查询年龄在9~12之间(含)的学生信息"""
        # SELECT * FROM school_student_info WHERE age BETWEEN 9 AND 12;
        # db.students.find({'age': {'$gte': 9, '$lte': 12}})
        result = Student.objects.filter(Q(age__gte=9) & Q(age__lte=12))
        print(result)
        return result
    def get_student_4(self):
        """查询所有12岁以上的男生和9岁以下的女生"""
        result = Student.objects.filter(Q(age__gt=12, sex=SexEnum.MAN) | Q(age__lt=9, sex=SexEnum.WOMAN))
        print(result)
        return result
    def get_grade(self):
        """查询大于等于60分的学生成绩信息"""
        result = Student.objects.filter(grades__score__gte=80)  # 注意这儿写法
        print(result)
        for i in result:
            print(i.grades)
        return result
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.get_one_student()
    obj.get_student_1()
    obj.get_student_2()
    obj.get_student_3()
    obj.get_student_4()
    obj.get_grade()

运行结果:  【注意:打印信息是由model中__call__函数设置决定的】

4.3、聚合统计

  • 满足条件的文档数:User.objects.count(),所有的结果集都可以使用
  • 求和/平均数:User.objects.filter().sum(field) / User.objects.filter().average(field)
from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def get_student_4(self):
        """查询所有12岁以上的男生和9岁以下的女生"""
        result = Student.objects.filter(Q(age__gt=12, sex=SexEnum.MAN) | Q(age__lt=9, sex=SexEnum.WOMAN))
        print(result)
        return result

    def get_student_5(self):
        """查询所有12岁以上的男生和9岁以下的女生总数"""
        result = Student.objects.filter(Q(age__gt=12, sex=SexEnum.MAN) | Q(age__lt=9, sex=SexEnum.WOMAN)).count()
        print(result)
        return result

    def get_man_sex(self):
        """统计性别为男的总人数,并求出其平均年龄和总年龄"""
        queryset = Student.objects.filter(sex='男')
        print(queryset)
        man_num_count = queryset.count()
        print(man_num_count)
        man_avg_age = queryset.average('age')
        print(man_avg_age)
        man_sum_age = queryset.sum('age')
        print(man_sum_age)
        return man_avg_age, man_sum_age
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.get_student_4()
    obj.get_student_5()
    obj.get_man_sex()

运行结果:

4.4、排序

  • -:倒叙排列
  • (+):正序排序,默认就是正序
  • Student.objects().order_by('field1', '-field2')
from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def get_max_min_age(self):
        """获取最大年龄和最小年龄的学生信息"""
        queryset_min_age = Student.objects.order_by('age').first()
        queryset_max_age = Student.objects.order_by('-age').first()
        print(queryset_min_age, queryset_min_age.age)
        print(queryset_max_age, queryset_max_age.age)

        return '200 OK'
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.get_max_min_age()

运行结果:

4.5、分页处理

  • 方式一,切片方式:User.objects.all()[10:15]
  • 方式二,.skip().limit():User.objects.skip(10).limit(5)
from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def paginate(self, page: int = 1, page_size: int = 5):
        """
        分页处理
        :param page: 当前是第几页
        :param page_size: 每页有多少数据
        :return:
        """
        #  方法一:切片
        start = (page - 1) * page_size
        end = start + page_size
        queryset1 = Student.objects.all()[start:end]
        print(queryset1)
        #  方法二:skip().limit()
        queryset2 = Student.objects.skip(start).limit(page_size)
        print(queryset2)
        return "200 OK"
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.paginate(1, 6)
    print("*" * 100)
    obj.paginate(1, 3)
    obj.paginate(2, 3)

运行结果:

五、修改和删除数据

5.1、修改数据

修改数据时一般先过滤数据,再修改

  • 修改一条数据:User.objects.filter().update_one()
  • 批量修改数据:User.objects.filter().update()

from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def update_one(self):
        """修改一条数据"""
        queryset = Student.objects.filter(stu_no='2438197')
        print(queryset)
        result = queryset.update_one(stu_name='白龙马', phone_no='16452412564')
        # result = queryset.update_one(stu_name='白龙马', unset__phone_no=True)
        print(result)
    def update_one_2(self):
        """修改一条数据"""
        queryset = Student.objects.filter(stu_no=3152784).first()
        print(queryset)
        if queryset:
            queryset.stu_name = '沙和尚'
            result = queryset.save()
            print(result)
            return "200 OK"
        else:
            return "error"
    def update_many(self):
        """将年龄10岁的学生年龄加一岁"""
        queryset = Student.objects.filter(age=10)
        print(queryset)
        queryset.update(inc__age=1)
        print(queryset)
        return "200 OK"
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.update_one()
    obj.update_one_2()
    obj.update_many()

运行结果:

5.2、删除数据

User.objects.filter().delete()

from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def delete_data(self):
        """删除年龄大于13岁的学生"""
        queryset_start = Student.objects.all()
        print(f"删除前学生总数量:{queryset_start.count()}")
        queryset = Student.objects.filter(age__gt=13)
        print(f'删除的学生的数量:{queryset.count()}')
        res = queryset.delete()
        print(f"删除的结果:{res}")
        queryset_end = Student.objects.all()
        print(f"删除后剩余学生总数量:{queryset_end.count()}")
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.delete_data()

运行结果:

附录:

main.py

import random
from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum, CourseGrade
class LearnMongoDBEngine(object):
    def __init__(self, info):
        self.info = info
        print(self.info)
    def add_one_student(self):
        """新增一个学生信息"""
        result = Student.objects.create(
            stu_no=random.randint(3000, 9999999),
            stu_name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            class_name='六年级三班',
            address=self.info['address'],
            phone_no=self.info['phone'],
            age=random.randint(10, 15),
            grades=[
                CourseGrade(course_name='语文', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='数学', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='英语', teacher=self.info['teacher'], score=random.randint(1, 100)),
            ]
        )
        # student = Student(
        #     stu_no=random.randint(3000, 9999999),
        #     stu_name=self.info['name'],
        #     sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
        #     class_name='六年级三班',
        #     address=self.info['address'],
        #     phone_no=self.info['phone'],
        #     age=random.randint(10, 15),
        #     grades=[
        #         CourseGrade(course_name='语文', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #         CourseGrade(course_name='数学', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #         CourseGrade(course_name='英语', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #     ]
        # )
        print(result, result.grades)
        # result = student.save()
        return result
    def get_one_student(self):
        """查询一个学生的信息"""
        student_info = Student.objects.first()
        print(student_info, student_info.id, student_info.stu_name, student_info.address)
        return student_info
    def get_all_student(self):
        """查询所有学生的信息"""
        student_all_info = Student.objects.all()
        print(student_all_info)
        return student_all_info
    def get_student_by_id(self, pk: str):
        """根据学生的id查询"""
        student_info_id = Student.objects.get(id=pk)
        print(student_info_id)
        return student_info_id
    def get_student_1(self):
        """获取大于12岁的学生信息"""
        result = Student.objects.filter(age__gt=12)
        print(result)
        return result
    def get_student_2(self):
        """获取所有姓李的学生"""
        result = Student.objects.filter(stu_name__startswith='李')
        print(result)
        return result
    def get_student_3(self):
        """查询年龄在9~12之间(含)的学生信息"""
        # SELECT * FROM school_student_info WHERE age BETWEEN 9 AND 12;
        # db.students.find({'age': {'$gte': 9, '$lte': 12}})
        result = Student.objects.filter(Q(age__gte=9) & Q(age__lte=12))
        print(result)
        return result
    def get_student_4(self):
        """查询所有12岁以上的男生和9岁以下的女生"""
        result = Student.objects.filter(Q(age__gt=12, sex=SexEnum.MAN) | Q(age__lt=9, sex=SexEnum.WOMAN))
        print(result)
        return result
    def get_student_5(self):
        """查询所有12岁以上的男生和9岁以下的女生总数"""
        result = Student.objects.filter(Q(age__gt=12, sex=SexEnum.MAN) | Q(age__lt=9, sex=SexEnum.WOMAN)).count()
        print(result)
        return result
    def get_man_sex(self):
        """统计性别为男的总人数,并求出其平均年龄和总年龄"""
        queryset = Student.objects.filter(sex='男')
        print(queryset)
        man_num_count = queryset.count()
        print(man_num_count)
        man_avg_age = queryset.average('age')
        print(man_avg_age)
        man_sum_age = queryset.sum('age')
        print(man_sum_age)
        return man_avg_age, man_sum_age
    def get_grade(self):
        """查询大于等于60分的学生成绩信息"""
        result = Student.objects.filter(grades__score__gte=80)  # 注意这儿写法
        print(result)
        for i in result:
            print(i.grades)
        return result
    def get_max_min_age(self):
        """获取最大年龄和最小年龄的学生信息"""
        queryset_min_age = Student.objects.order_by('age').first()
        queryset_max_age = Student.objects.order_by('-age').first()
        print(queryset_min_age, queryset_min_age.age)
        print(queryset_max_age, queryset_max_age.age)
        return '200 OK'
    def paginate(self, page: int = 1, page_size: int = 5):
        """
        分页处理
        :param page: 当前是第几页
        :param page_size: 每页有多少数据
        :return:
        """
        #  方法一:切片
        start = (page - 1) * page_size
        end = start + page_size
        queryset1 = Student.objects.all()[start:end]
        print(queryset1)
        #  方法二:skip().limit()
        queryset2 = Student.objects.skip(start).limit(page_size)
        print(queryset2)
        return "200 OK"
    def update_one(self):
        """修改一条数据"""
        queryset = Student.objects.filter(stu_no='2438197')
        print(queryset)
        result = queryset.update_one(stu_name='白龙马', phone_no='16452412564')
        # result = queryset.update_one(stu_name='白龙马', unset__phone_no=True)
        print(result)
    def update_one_2(self):
        """修改一条数据"""
        queryset = Student.objects.filter(stu_no=3152784).first()
        print(queryset)
        if queryset:
            queryset.stu_name = '沙和尚'
            result = queryset.save()
            print(result)
            return "200 OK"
        else:
            return "error"
    def update_many(self):
        """将年龄10岁的学生年龄加一岁"""
        queryset = Student.objects.filter(age=10)
        print(queryset)
        queryset.update(inc__age=1)
        print(queryset)
        return "200 OK"
    def delete_data(self):
        """删除年龄大于13岁的学生"""
        queryset_start = Student.objects.all()
        print(f"删除前学生总数量:{queryset_start.count()}")
        queryset = Student.objects.filter(age__gt=13)
        print(f'删除的学生的数量:{queryset.count()}')
        res = queryset.delete()
        print(f"删除的结果:{res}")
        queryset_end = Student.objects.all()
        print(f"删除后剩余学生总数量:{queryset_end.count()}")
if __name__ == '__main__':
    #  自我测试代码
    pass

model.py

from mongoengine import Document, connect, EnumField, StringField, IntField, ListField, EmbeddedDocument, \
    EmbeddedDocumentField
from enum import Enum
#  连接到User数据库
connect('user', host='192.168.124.104', port=27017)
class SexEnum(Enum):
    MAN = '男'
    WOMAN = '女'
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, required=True, verbose_name='成绩')
    def __repr__(self):
        return f"CourseGrade({self.course_name},{self.score})"
    def __str__(self):
        return self.__repr__()
class Student(Document):
    """学生信息"""
    # verbose_name 自定义参数,用于显示定义域的名称
    stu_no = IntField(required=True, unique=True, verbose_name='学号')
    stu_name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性别')
    class_name = StringField(max_length=10, verbose_name='班级')
    address = StringField(max_length=255, verbose_name='家庭住址')
    phone_no = StringField(max_length=11, verbose_name='电话号码')
    age = IntField(min_value=0, max_value=150, verbose_name='年龄')
    grades = ListField(EmbeddedDocumentField(CourseGrade), verbose_name='成绩数组')
    meta = {
        #  指定文档的集合
        'collection': 'students',
        #  指定排序,可以指定多个域。例如:'age':根据年龄升序,'-age':根据年龄降序
        'ordering': ['-age'],
        'strict': False  # 设置非严格校验字段则不需要吧所有字段都声明
    }
    def __repr__(self):
        return f'Grade({self.stu_no}, {self.stu_name})'
    def __str__(self):
        return self.__repr__()
class Grade(Document):
    """学生成绩"""
    # verbose_name 自定义参数,用于显示定义域的名称
    stu_no = IntField(required=True, verbose_name="学号")
    stu_name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性别')
    class_name = StringField(max_length=10, verbose_name='班级')
    address = StringField(max_length=255, verbose_name='家庭住址')
    phone_no = StringField(max_length=11, verbose_name='电话号码')
    age = IntField(min_value=0, max_value=150, verbose_name='年龄')
    grades = EmbeddedDocumentField(CourseGrade, verbose_name='成绩')
    meta = {
        # 指定文档的集合
        'collection': 'grades',
        # 指定排序,可以指定多个域。例如:'age':根据年龄升序,'-age':根据年龄降序
        'ordering': ['-age']
    }
    def __repr__(self):
        return f'Grade({self.stu_no}, {self.stu_name})'
    def __str__(self):
        return self.__repr__()

官方文档:
https://docs.mongoengine.org/guide/querying.html

到此这篇关于python中mongoengine库用法详解的文章就介绍到这了,更多相关python mongoengine库内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • win系统下为Python3.5安装flask-mongoengine 库

    环境: windows 10.python 3.5.flask-mongoengine 0.8.2或0.9.0 使用以下命令安装 flask-mongoengine pip install flask-mongoengine 会出现以下错误: 复制代码 代码如下: flask-mongoengine-0.8.2\setup.py", line 10, in <module> UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6

  • 在Python中使用mongoengine操作MongoDB教程

    最近重新拾起Django,但是Django并不支持mongodb,但是有一个模块mongoengine可以实现Django Model类似的封装.但是mongoengine的中文文档几乎没有,有的也是简短的几句介绍和使用.下面我就分享一下我在使用过程中所记录下的一些笔记,可能有点乱.大家可以参考一下. 安装mongoengine easy_install pymongo # 依赖库 easy_install mongoengine 基本使用 from mongoengine import * f

  • 在Python中使用MongoEngine操作数据库教程实例

    这篇文章主要介绍了在Python中使用MongoEngine操作数据库教程实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 pymongo来操作MongoDB数据库,但是直接把对于数据库的操作代码都写在脚本中,这会让应用的代码耦合性太强,而且不利于代码的优化管理 一般应用都是使用MVC框架来设计的,为了更好地维持MVC结构,需要把数据库操作部分作为model抽离出来,这就需要借助MongoEngine MongoEngine是一个对象文档映射

  • Python利用ORM控制MongoDB(MongoEngine)的步骤全纪录

    简介: MongoEngine 是一个Document-Object Mapper (想一下ORM, 但它是针对文档型数据库),Python通过它与MongoDB交互.你可能会说那PyMongo也是ORM啊,在Python中一切都是对象,但我们所说的ORM中的Object在指Python中的自定义类,而不是内置类型.MongoEngine或MongoKit将MongoDB的数据映射成自定义类实例,它们都是基于PyMongo的. 我们可以跟关系型数据库的Python客户端MySQLdb,以及ORM

  • 详解python中mongoengine库用法

    目录 一.MongoDB的安装与连接 二.MongoEngine模型介绍 2.1.ODM模型介绍 2.2.常见数据类型 2.3.数据类型通用参数 2.4.类属性meta常见配置项 2.5.文档的嵌套模型 三.添加数据 3.1.方式一 3.2.方式二:使用create()方法 四.查询数据 4.1.单个文档查询 4.2.条件查询 4.3.聚合统计 4.4.排序 4.5.分页处理 五.修改和删除数据 5.1.修改数据 5.2.删除数据 一.MongoDB的安装与连接 安装:pip install m

  • 详解Python中第三方库Faker

    项目开发初期,为了测试方便,我们总要造不少假数据到系统中,尽量模拟真实环境. 比如要创建一批用户名,创建一段文本,电话号码,街道地址.IP地址等等. 平时我们基本是键盘一顿乱敲,随便造个什么字符串出来,当然谁也不认识谁. 现在你不要这样做了,用Faker就能满足你的一切需求. 1. 安装 pip install Faker 2. 简单使用 >>> from faker import Faker >>> fake = Faker(locale='zh_CN') >&

  • 详解Python中pyautogui库的最全使用方法

    在使用Python做脚本的话,有两个库可以使用,一个为PyUserInput库,另一个为pyautogui库.就本人而言,我更喜欢使用pyautogui库,该库功能多,使用便利.下面给大家介绍一下pyautogui库的使用方法.在cmd命令框中输入pip3 install pyautogui即可安装该库! 常用操作 我们在pyautogui库中常常使用的方法,如下: import pyautogui pyautogui.PAUSE = 1 # 调用在执行动作后暂停的秒数,只能在执行一些pyaut

  • 一文详解Python中复合语句的用法

    目录 Python复合语句 1.if 语句 2.while 语句 3.for 语句 4.try 语句 5.with 语句 6.match 语句 Python复合语句 复合语句是包含其它语句(语句组)的语句:它们会以某种方式影响或控制所包含其它语句的执行.通常,复合语句会跨越多行,虽然在某些简单形式下整个复合语句也可能包含于一行之内. if.while和for语句用来实现传统的控制流程构造.try语句为一组语句指定异常处理和/和清理代码,而with语句允许在一个代码块周围执行初始化和终结化代码.函

  • 详解python中静态方法staticmethod用法

    在开发的时候, 可以使用类对方法进行封装,如果某一个方法需要访问到对象的实例属性,可以把这个方法封装成一个实例方法.如果某一个方法不需要访问对象的实例属性,但是需要访问到类的类属性,这个时候就可以考虑把这个方法封装成一个类方法.一个实例方法, 一个类方法,这是两种方法类型,但是在开发中还有一种情况,如果要封装的某一个方法,既不需要访问到对象的实例属性,也不需要访问类的类属性,这个时候就可以考虑把这个方法封装成一个静态方法. 在开发中,如果类中的某个方法既不需要访问实例属性或者调用实例方法,同时也

  • 详解python中*号的用法

    1.表示乘号 2.表示倍数,例如: def T(msg,time=1): print((msg+' ')*time) T('hi',3) 打印结果(打印3次): hi hi hi 3.单个 * (1).如:*parameter是用来接受任意多个参数并将其放在一个元组中. >>> def demo(*p): print(p) >>> demo(1,2,3) (1, 2, 3) (2).函数在调用多个参数时,在列表.元组.集合.字典及其他可迭代对象作为实参,并在前面加 *

  • 详解python中docx库的安装过程

    python中docx库的简介 python-docx包,这是一个很强大的包,可以用来创建docx文档,包含段落.分页符.表格.图片.标题.样式等几乎所有的word文档中能常用的功能都包含了,这个包的主要功能便是用来创建文档,相对来说用来修改功能不是很强大.一般情况下在Anaconda中不自带,需另行下载. 导入docx的方法 我的实现方法是通过pip工具在线下载:首先打开cmd命令窗口,然后输入pip install python-docx,然后回车静等.最后命令行中出现Successfull

  • 详解python 中in 的 用法

    in在Python中是操作符,具体来说是成员操作符.就是对于序列(字符串,元组,列表)或集合(set)或映射(字典)这些数据类型做成员判断,自然成员判断的返回是在其中和不在其中,用Python的说法就是True,False ,也就是说xxinxxx是可以用在诸如:if xx in xxx, while xx in xxx 等等典型的需要判断的情况(不止如此,还有更多). 1.   作用为 成员运算符   在字符串内操作,如果字符串包含相关字符 则返回True,如果不包含则返回False   当然

  • Python中optparser库用法实例详解

    本文研究的主要是Python中optparser库的相关内容,具体如下. 一直以来对optparser不是特别的理解,今天就狠下心,静下心研究了一下这个库.当然了,不敢说理解的很到位,但是足以应付正常的使用了.废话不多说,开始今天的分享吧. 简介 optparse模块主要用来为脚本传递命令参数功能. 引入 在IDE中引入optparser是很方便的. from optparser import OptionParser 初始化 相对而言,初始化需要我们多注意一点点了. 因为我们有两种不同的方式来

  • python中openpyxl库用法详解

    目录 一.读取数据 1.1 从工作簿中取得工作表 1.2 从表中取得单元格 1.3 从表中取得行和列 二.写入数据 2.1 创建Workbook对象来创建Excel文件并保存 2.2 案例分析一 :爬取数据并保存excel中 2.3 案例分析二: 操作单元格中内容样式并保存数据 2.4 案例分析三:将列表数据写入excel中 openpyxl模块是一个读写Excel 文档的Python库,openpyxl是一个比较综合的工具,能够同时读取和修改Excel文档. openpyxl.load_wor

随机推荐