python中mongoengine库用法详解2

更多mongoengine库用法详见博文:

python中mongoengine库用法详解_IT之一小佬的博客-CSDN博客

官方文档:MongoEngine User Documentation — MongoEngine 0.25.0 documentation 

1、 数据库结构定义

1.1 时间字段定义

DateTimeField类型:

create_time_utc = DateTimeField(default=datetime.utcnow())
create_time_now = DateTimeField(default=datetime.now())

也可以这样写,推荐: 

create_time_utc = DateTimeField(default=datetime.utcnow)
create_time_now = DateTimeField(default=datetime.now)

DateField类型:

create_date_utc = DateField(default=datetime.utcnow().date)
create_date_now = DateField(default=datetime.now().date)

2、条件查询

2.1 比较运算符$in

in:表示在数组内

示例代码:

from model import StudentInfo, SexEnum
import random


class LearnMongoDBEngine(object):
    def __init__(self, info):
        self.info = info
        # print(self.info)

    def add_one_student(self):
        """新增一个学生信息"""
        student = StudentInfo(
            name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            age=random.randint(10, 15),
            teachers=self.info['teachers']
        )
        # print(student)
        result = student.save()
        return result

    def get_one_student(self):
        """查询一个学生的信息"""
        student_info = StudentInfo.objects.first()
        # print(student_info)
        return student_info

    def get_all_student(self):
        """查询所有学生的信息"""
        student_all_info = StudentInfo.objects.all()
        # print(student_all_info)
        return student_all_info

    def condition_query_in(self):
        """$in:在数组内"""
        student_in = StudentInfo.objects.filter(teachers__in=["王老师"])
        print(student_in, type(student_in))
        for i in student_in:
            print(i.name, i.sex, i.age, i.teachers)

        print("*" * 100)
        
        # 注意:这种情况下使用[0],若数据查询不到时会报错
        student_in = StudentInfo.objects.filter(teachers__in=["王老师"])[0]
        print(student_in, type(student_in))
        print(student_in.name, student_in.sex, student_in.age, student_in.teachers)

        print("*" * 100)

        # 当列表中仅有一个值时,可以使用等号
        student_in = StudentInfo.objects.filter(teachers=["孙老师"])[0]
        print(student_in)
        print(student_in.name, student_in.sex, student_in.age, student_in.teachers)

        print("*" * 100)

        # 当teachers字段中有一个值在列表中,就会被查询出来
        student_in = StudentInfo.objects.filter(teachers__in=["王老师", "孙老师"])
        print(student_in, type(student_in))
        for i in student_in:
            print(i.name, i.sex, i.age, i.teachers)

        print("*" * 100)

        # 当teachers字段列表中第一个值在列表中时,就会被查询出来
        student_in = StudentInfo.objects.filter(teachers__in__0=["王老师", "孙老师"])
        print(student_in, type(student_in))
        for i in student_in:
            print(i.name, i.sex, i.age, i.teachers)

        print("*" * 100)

        # 当teachers字段列表中第一个值等于某个值时,就会被查询出来
        student_in = StudentInfo.objects.filter(teachers__0="王老师")
        print(student_in, type(student_in))
        for i in student_in:
            print(i.name, i.sex, i.age, i.teachers)
        return student_in


if __name__ == '__main__':
    info = {"name": "王五", "teachers": ["孙老师"]}
    obj = LearnMongoDBEngine(info)
    # obj.add_one_student()
    # obj.get_one_student()
    # obj.get_all_student()
    obj.condition_query_in()

运行结果:

2.2 定义query自定义函数并继承

model.py:

from mongoengine import Document, connect, EnumField, StringField, IntField, ListField, DateTimeField, DateField
from enum import Enum
from datetime import datetime

#  连接到User数据库
# connect('user', host='192.168.124.104', port=27017)
connect('user', host='mongodb://root:88888888@192.168.124.49:27017/?authSource=admin')


class SexEnum(Enum):
    MAN = '男'
    WOMAN = '女'


class BaseFunc(object):
    @classmethod
    def query(cls, exception=False, **kwargs):
        doc = cls.objects(**kwargs).first()
        if doc is None:
            if exception:
                return '查询结果为空!'
            return None
        return doc


class StudentInfo(Document, BaseFunc):
    """学生信息"""
    name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性别')
    age = IntField(min_value=0, max_value=150, verbose_name='年龄')
    teachers = ListField(StringField(max_length=150), verbose_name='老师们')
    create_time_utc = DateTimeField(default=datetime.utcnow)
    create_time_now = DateTimeField(default=datetime.now)
    create_date_utc = DateField(default=datetime.utcnow().date)
    create_date_now = DateField(default=datetime.now().date)

    meta = {
        #  指定文档的集合
        'collection': 'students_info',
        'ordering': ['-age'],
        'strict': False
    }

    def __repr__(self):
        return f'StudentInfo({self.name}, {self.sex}, {self.age}, {self.teachers})'

    def __str__(self):
        return self.__repr__()

main.py:

from model import StudentInfo, SexEnum
import random


class LearnMongoDBEngine(object):
    def __init__(self, info):
        self.info = info

    def add_one_student(self):
        """新增一个学生信息"""
        student = StudentInfo(
            name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            age=random.randint(10, 15),
            teachers=self.info['teachers']
        )
        result = student.save()
        return result

    def get_one_student(self, name, exception=False):
        """查询一个学生的信息"""
        student_info = StudentInfo.query(name=name, exception=exception)
        return student_info

    def get_all_student(self):
        """查询所有学生的信息"""
        student_all_info = StudentInfo.objects.all()
        return student_all_info


if __name__ == '__main__':
    info = {"name": "王五6", "teachers": ["孙老师"]}
    obj = LearnMongoDBEngine(info)
    one_student = obj.get_one_student(name='王五4', exception=True)
    print(one_student)
    one_student = obj.get_one_student(name='王五41', exception=True)
    print(one_student)
    all_student = obj.get_all_student()
    print(all_student)

运行结果:

3、更新数据

3.1 update()使用

        update()是原子更新,使用时是局部更新。

示例代码:

from model import StudentInfo, SexEnum
import random


class LearnMongoDBEngine(object):
    def __init__(self, info):
        self.info = info
        # print(self.info)

    def add_one_student(self):
        """新增一个学生信息"""
        student = StudentInfo(
            name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            age=random.randint(10, 15),
            teachers=self.info['teachers']
        )
        # print(student)
        result = student.save()
        return result

    def get_one_student(self):
        """查询一个学生的信息"""
        student_info = StudentInfo.objects.first()
        # print(student_info)
        return student_info

    def get_all_student(self):
        """查询所有学生的信息"""
        student_all_info = StudentInfo.objects.all()
        # print(student_all_info)
        return student_all_info


if __name__ == '__main__':
    info = {"name": "王五", "teachers": ["孙老师"]}
    obj = LearnMongoDBEngine(info)
    # obj.add_one_student()
    one_student = obj.get_one_student()
    print(one_student)
    print(type(one_student))
    one_student.update(age=20)
    all_student = obj.get_all_student()
    print(all_student)

运行结果:

3.2 类中自定义update()方法

示例代码:

from model import StudentInfo, SexEnum
import random


class LearnMongoDBEngine(object):
    def __init__(self, info):
        self.info = info
        # print(self.info)

    def add_one_student(self):
        """新增一个学生信息"""
        student = StudentInfo(
            name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            age=random.randint(10, 15),
            teachers=self.info['teachers']
        )
        # print(student)
        result = student.save()
        return result

    def get_one_student(self):
        """查询一个学生的信息"""
        student_info = StudentInfo.objects.first()
        # print(student_info)
        return student_info

    def get_all_student(self):
        """查询所有学生的信息"""
        student_all_info = StudentInfo.objects.all()
        # print(student_all_info)
        return student_all_info

    def update(self, name=None, sex=None, age=None):
        """更新一条数据"""
        student_name = StudentInfo.objects(name=name).first()
        if not student_name:
            return f"{name}不存在!"
        modify = False
        if sex is not None and student_name.sex != sex:
            student_name.sex = sex
            modify = True
        if age is not None and student_name.age != age:
            student_name.age = age
            modify = True
        if modify:
            student_name.save()
        return self


if __name__ == '__main__':
    info = {"name": "王五", "teachers": ["孙老师"]}
    obj = LearnMongoDBEngine(info)
    # obj.add_one_student()
    one_student = obj.get_one_student()
    print(one_student)
    print(type(one_student))
    obj.update(name='王五4', age=26)
    all_student = obj.get_all_student()
    print(all_student)

运行结果:

3.3 集合类中定义封装update方法

model.py

from mongoengine import Document, connect, EnumField, StringField, IntField, ListField, DateTimeField, DateField
from enum import Enum
from datetime import datetime

#  连接到User数据库
# connect('user', host='192.168.124.104', port=27017)
connect('user', host='mongodb://root:88888888@192.168.124.49:27017/?authSource=admin')


class SexEnum(Enum):
    MAN = '男'
    WOMAN = '女'


class BaseFunc(object):

    def update(self, **kwargs):
        return self.update(**kwargs)


class StudentInfo(Document, BaseFunc):
    """学生信息"""
    name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性别')
    age = IntField(min_value=0, max_value=150, verbose_name='年龄')
    teachers = ListField(StringField(max_length=150), verbose_name='老师们')
    create_time_utc = DateTimeField(default=datetime.utcnow)
    create_time_now = DateTimeField(default=datetime.now)
    create_date_utc = DateField(default=datetime.utcnow().date)
    create_date_now = DateField(default=datetime.now().date)

    meta = {
        #  指定文档的集合
        'collection': 'students_info',
        'ordering': ['-age'],
        'strict': False
    }

    def raw_update(self, **kwargs):
        return super().update(**kwargs)

    def __repr__(self):
        return f'StudentInfo({self.name}, {self.sex}, {self.age}, {self.teachers})'

    def __str__(self):
        return self.__repr__()

main.py

from model import StudentInfo


class LearnMongoDBEngine(object):
    def __init__(self, info):
        self.info = info

    def get_one_student(self):
        """查询一个学生的信息"""
        student_info = StudentInfo.objects.first()
        # print(student_info)
        return student_info

    def get_all_student(self):
        """查询所有学生的信息"""
        student_all_info = StudentInfo.objects.all()
        return student_all_info


if __name__ == '__main__':
    info = {"name": "王五6", "teachers": ["孙老师"]}
    obj = LearnMongoDBEngine(info)
    one_student = obj.get_one_student()
    print(one_student)
    one_student.raw_update(age=25)
    one_student = obj.get_one_student()
    print(one_student)
    all_student = obj.get_all_student()
    print(all_student)

运行结果:

3.4 原子更新操作

原子更新的语法类似于查询语法,但修饰符出现在字段之前,而不是之后。

  • set– 设置一个特定的值
  • set_on_insert– 仅当这是新文档时才设置 `需要添加 upsert=True`_
  • unset– 删除特定值(自 MongoDB v1.3 起)
  • max– 仅在值较大时更新
  • min– 仅在值较小时更新
  • inc– 将一个值增加给定的数量
  • dec– 将一个值减少给定的量
  • push– 将值附加到列表
  • push_all– 将几个值附加到列表
  • pop–根据值删除列表的第一个或最后一个元素
  • pull– 从列表中删除一个值
  • pull_all– 从列表中删除多个值
  • add_to_set– 仅在不在列表中时才向列表添加值
  • rename– 重命名键名

示例代码:

from model import StudentInfo

all_student_info = StudentInfo.objects.all()
print(all_student_info)

one_student_info = StudentInfo.objects(name="王五4").first()
print(one_student_info)
print(type(one_student_info))

#  inc
StudentInfo.objects(name="王五4").update(inc__age=3)
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

#  dec
StudentInfo.objects(name="王五4").update(dec__age=2)
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

# set
StudentInfo.objects(name="王五4").update(set__teachers__0="孙老师")
# StudentInfo.objects(name="王五4").update(teachers__0="王老师")
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

# unset
StudentInfo.objects(name="王五4").update(unset__teachers__0="王老师")
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

# push
StudentInfo.objects(name="王五4").update(push__teachers="董老师")
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

StudentInfo.objects(name="王五4").update(push__teachers=["张老师", "刘老师"])
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

# push_all
StudentInfo.objects(name="王五4").update(push_all__teachers=["赵老师", "钱老师"])
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

# pop
pop_ret = StudentInfo.objects(name="王五4").update(pop__teachers=1)  # 删除最后一个
print(pop_ret)
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

# pull
pop_ret = StudentInfo.objects(name="王五4").update(pull__teachers="董老师")  # 删除符合条件的所有值
print(pop_ret)
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

# pull_all
pop_ret = StudentInfo.objects(name="王五4").update(pull_all__teachers=["赵老师", "钱老师", "张老师"])  # 删除符合列表中条件的所有值
print(pop_ret)
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

# add_to_set
StudentInfo.objects(name="王五4").update(add_to_set__teachers=["赵老师", "钱老师", "张老师", "孙老师"])  # 添加不存在的列表中的所有值
StudentInfo.objects(name="王五4").update(add_to_set__teachers="李老师")  # 当存在时不添加,否则添加
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

# rename
StudentInfo.objects(name="王五4").update(rename__sex="gender")
one_student_info.reload()  # the document has been changed, so we need to reload it
print(one_student_info)

运行结果:

注意:使用des时,注意min_value的设置值。

注意:如果未指定修饰符运算符,则默认值为$set. 所以下面的句子是相同的:

StudentInfo.objects(name="王五4").update(set__teachers__0="王老师")
StudentInfo.objects(name="王五4").update(teachers__0="王老师")

注意:使用rename时,直接把该条数据的键值给修改了。

附录:

model.py:

from mongoengine import Document, connect, EnumField, StringField, IntField, ListField, DateTimeField, DateField
from enum import Enum
from datetime import datetime

#  连接到User数据库
# connect('user', host='192.168.124.104', port=27017)
connect('user', host='mongodb://root:88888888@192.168.124.49:27017/?authSource=admin')


class SexEnum(Enum):
    MAN = '男'
    WOMAN = '女'


class BaseFunc(object):
    @classmethod
    def query(cls, exception=False, **kwargs):
        doc = cls.objects(**kwargs).first()
        if doc is None:
            if exception:
                return '查询结果为空!'
            return None
        return doc

    def update(self, **kwargs):
        return self.update(**kwargs)


class StudentInfo(Document, BaseFunc):
    """学生信息"""
    name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性别')
    age = IntField(min_value=0, max_value=150, verbose_name='年龄')
    teachers = ListField(StringField(max_length=150), verbose_name='老师们')
    create_time_utc = DateTimeField(default=datetime.utcnow)
    create_time_now = DateTimeField(default=datetime.now)
    create_date_utc = DateField(default=datetime.utcnow().date)
    create_date_now = DateField(default=datetime.now().date)

    meta = {
        #  指定文档的集合
        'collection': 'students_info',
        'ordering': ['-age'],
        'strict': False
    }

    def raw_update(self, **kwargs):
        return super().update(**kwargs)

    def __repr__(self):
        return f'StudentInfo({self.name}, {self.sex}, {self.age}, {self.teachers})'

    def __str__(self):
        return self.__repr__()

main.py:

from model import StudentInfo, SexEnum
import random


class LearnMongoDBEngine(object):
    def __init__(self, info):
        self.info = info
        # print(self.info)

    def add_one_student(self):
        """新增一个学生信息"""
        student = StudentInfo(
            name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            age=random.randint(10, 15),
            teachers=self.info['teachers']
        )
        # print(student)
        result = student.save()
        return result

    def get_one_student(self):
        """查询一个学生的信息"""
        student_info = StudentInfo.objects.first()
        # print(student_info)
        return student_info

    def get_one_student2(self, name, exception=False):
        """查询一个学生的信息"""
        student_info = StudentInfo.query(name=name, exception=exception)
        return student_info

    def get_all_student(self):
        """查询所有学生的信息"""
        student_all_info = StudentInfo.objects.all()
        # print(student_all_info)
        return student_all_info

    def update(self, name=None, sex=None, age=None):
        """更新一条数据"""
        student_name = StudentInfo.objects(name=name).first()
        if not student_name:
            return f"{name}不存在!"
        modify = False
        if sex is not None and student_name.sex != sex:
            student_name.sex = sex
            modify = True
        if age is not None and student_name.age != age:
            student_name.age = age
            modify = True
        if modify:
            student_name.save()
        return self

    def condition_query_in(self):
        """$in:在数组内"""
        student_in = StudentInfo.objects.filter(teachers__in=["王老师"])
        print(student_in, type(student_in))
        for i in student_in:
            print(i.name, i.sex, i.age, i.teachers)

        print("*" * 100)

        # 注意:这种情况下使用[0],若数据查询不到时会报错
        student_in = StudentInfo.objects.filter(teachers__in=["王老师"])[0]
        print(student_in, type(student_in))
        print(student_in.name, student_in.sex, student_in.age, student_in.teachers)

        print("*" * 100)

        # 当列表中仅有一个值时,可以使用等号
        student_in = StudentInfo.objects.filter(teachers=["孙老师"])[0]
        print(student_in)
        print(student_in.name, student_in.sex, student_in.age, student_in.teachers)

        print("*" * 100)

        # 当teachers字段中有一个值在列表中,就会被查询出来
        student_in = StudentInfo.objects.filter(teachers__in=["王老师", "孙老师"])
        print(student_in, type(student_in))
        for i in student_in:
            print(i.name, i.sex, i.age, i.teachers)

        print("*" * 100)

        # 当teachers字段列表中第一个值在列表中时,就会被查询出来
        student_in = StudentInfo.objects.filter(teachers__in__0=["王老师", "孙老师"])
        print(student_in, type(student_in))
        for i in student_in:
            print(i.name, i.sex, i.age, i.teachers)

        print("*" * 100)

        # 当teachers字段列表中第一个值等于某个值时,就会被查询出来
        student_in = StudentInfo.objects.filter(teachers__0="王老师")
        print(student_in, type(student_in))
        for i in student_in:
            print(i.name, i.sex, i.age, i.teachers)
        return student_in


if __name__ == '__main__':
    info = {"name": "王五", "teachers": ["孙老师"]}
    obj = LearnMongoDBEngine(info)
    # obj.add_one_student()
    # obj.get_one_student()
    # obj.get_all_student()
    obj.condition_query_in()
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值