from datetime import datetime
from mongoengine import (
Document, EmbeddedDocument,
StringField, IntField, DateTimeField,
ListField, EmbeddedDocumentField, ReferenceField,
connect
)
# ==========================================
# 1. 建立与 MongoDB 的连接
# ==========================================
# 连接到本地的 'blog_database' 数据库
connect(db='blog_database', host='mongodb://localhost:27017/')
# ==========================================
# 2. 定义数据模型(Schema)
# ==========================================
# 嵌入式文档(Embedded Document):用于文章底部的评论
class Comment(EmbeddedDocument):
user_name = StringField(required=True, max_length=50)
content = StringField(required=True)
# created_at = DateTimeField(default=datetime.utcnow)
created_at = DateTimeField(default=lambda: datetime.now(timezone.utc), required=True)
# 主文档(Document):用户表
class User(Document):
name = StringField(required=True, max_length=50)
email = StringField(required=True, unique=True)
age = IntField(min_value=0)
meta = {'collection': 'users'} # 映射到 MongoDB 的 'users' 集合
# 主文档(Document):文章表(包含关联关系与嵌入式文档)
class Post(Document):
title = StringField(required=True, max_length=120)
content = StringField(required=True)
author = ReferenceField(User, required=True) # 外键引用:关联 User 文档
tags = ListField(StringField(max_length=30)) # 列表字段:标签
comments = ListField(EmbeddedDocumentField(Comment)) # 嵌套评论列表
# created_at = DateTimeField(default=datetime.utcnow)
created_at = DateTimeField(default=lambda: datetime.now(timezone.utc), required=True)
meta = {'collection': 'posts'} # 映射到 'posts' 集合
# ==========================================
# 3. 增、删、改、查(CRUD)业务逻辑
# ==========================================
def main():
print("=== 1. 【增】Create 操作 ===")
# 创建并保存用户
user1 = User(name="张三", email="[email protected]", age=28)
user1.save() # 写入数据库
user2 = User(name="李四", email="[email protected]", age=32)
user2.save()
# 创建并保存文章(关联张三,并添加标签和评论)
post1 = Post(
title="MongoEngine 快速入门",
content="这是一篇关于如何使用 Python 和 MongoEngine 操作 MongoDB 的文章。",
author=user1,
tags=["Python", "MongoDB", "Database"],
comments=[
Comment(user_name="李四", content="写得非常好!")
]
)
post1.save()
print(f"成功创建文章: {post1.title}, ID: {post1.id}")
print("\n=== 2. 【查】Read 操作 ===")
# 2.1 查询单个文档 (get 或 objects().first())
found_user = User.objects(name="张三").first()
print(f"查找到用户: {found_user.name}, 邮箱: {found_user.email}")
# 2.2 条件查询与关联查询 (objects 配合条件过滤)
# 查找标签包含 "Python" 的文章
python_posts = Post.objects(tags="Python")
for p in python_posts:
print(f"文章标题: {p.title}")
print(f"文章作者(自动触发引用填充): {p.author.name}") # ReferenceField 会自动 Dereference
print("\n=== 3. 【改】Update 操作 ===")
# 3.1 实例修改并保存
found_user.age = 29
found_user.save() # 执行更新
print(f"更新后张三的年龄: {User.objects(name='张三').first().age}")
# 3.2 使用 update() 方法直接在数据库中批量/原子更新
Post.objects(title="MongoEngine 快速入门").update(
push__tags="ODM", # 向 tags 列表追加一个元素
set__content="更新后的文章内容:更详细的 MongoEngine 教程。" # 修改普通字段
)
updated_post = Post.objects(title="MongoEngine 快速入门").first()
print(f"更新后的标签: {updated_post.tags}")
print(f"更新后的内容: {updated_post.content}")
print("\n=== 4. 【删】Delete 操作 ===")
# 4.1 删除单个文档的实例
target_user = User.objects(name="李四").first()
target_user.delete()
# 4.2 通过条件直接删除多个文档
deleted_count = User.objects(name="李四").delete()
print(f"已删除用户数量: {deleted_count}")
print(f"剩余用户总数: {User.objects.count()}")
if __name__ == "__main__":
main()
增删改查(CRUD)实现细节:
Create(增):实例化定义好的模型类(如 User(...)),然后调用 .save() 方法即可写入数据库。
Read(查):所有查询的入口都是 .objects(QuerySet 管理器)。
支持链式调用和丰富查询符,例如 User.objects(age__gte=18) 对应 MongoDB 的 { "age": { "$gte": 18 } }。
Update(改):对象级修改:直接修改对象的属性后调用 .save()。
原子更新符(QuerySet Update):使用 .update() 配合操作符(如 set__xxx、push__xxx、inc__xxx 等),直接在数据库层面高效更新,避免全量传输。
Delete(删):既可以对查询出来的对象调用 .delete(),也可以直接通过 .objects(...).delete() 批量删除。