一、介绍
MongoDB是一个免费的开源NoSQL数据库程序。它将数据存储在文档集合中,其中文档类似于传统关系数据库系统中的一行。它没有用于在集合中存储数据的固定架构;您可以将数据存储在键值对中,就像 Python 字典一样。灵活的数据模型和对水平扩展的支持等功能允许您在需求更改时进行更改或缩放数据库。
MongoEngine是一个对象文档映射器(ODM),它允许你的Python应用程序与MongoDB数据库进行交互。它提供了一个声明性 API,您可以在其中使用 Python 类和对象与数据库中的文档进行交互。这个抽象层使开发人员更容易与MongoDB数据库进行交互,有助于减少开发时间,并使数据库逻辑不易出错。
本文介绍 MongoEngine ODM 的安装和配置,定义文档架构、执行创建、读取、更新和删除 (CRUD) 操作以及从数据库中查询筛选数据的步骤。它还介绍了文档引用、迁移和元选项的基础知识。
二、准备工作
- 在 Vultr 部署 Ubuntu 20.04 实例。
- 创建具有 sudo 权限的非 root 用户。
- 以非根用户身份登录您的实例。
- 在实例上安装 MongoDB 数据库服务器。
三、设置环境
安装 MongoEngine 库。
$ pip install mongoengine
设置新的项目目录。
$ mkdir ~/mongoengine_demo
切换到项目目录。
$ cd ~/mongoengine_demo
四、连接到数据库
您可以使用 MongoEngine 模块中的函数与 MongoDB 服务器建立连接。必须将主机名、端口、数据库等值作为参数传递。connect()
使用文本编辑器创建一个名为 的新 Python 文件。app.py
$ nano app.py
将以下内容添加到文件中,并使用 + 然后保存文件。CTRLXENTER
from mongoengine import *
client = connect('mongoengine_demo')
上面的代码使用默认主机和端口与MongoDB服务器建立连接。作为参数传递的字符串引用数据库的名称。如果数据库不存在,它会尝试使用传递给函数的名称创建新数据库。127.0.0.1
27017
connect()
以下示例演示如何使用非默认值连接到 MongoDB 服务器。
connect('database_name', username='username', password='password', authentication_source='admin')
还可以使用该参数与多个数据库或数据库服务器建立连接。有关详细信息,请参阅 MongoEngine 文档中的多个数据库部分。alias
五、定义文档架构
存储在MongoDB数据库中的文档没有任何固定的模式。但是,定义文档架构可确保数据结构和验证,从而使数据库逻辑不易出错。
MongoEngine ODM允许您创建固定或动态文档架构。您可以从 MongoEngine 模块继承 or 类以创建新的文档类并使用字段对象定义每个字段,请参阅 MongoEngine 文档中的字段部分以查找所有可用的字段类型。Document
DynamicDocument
编辑在上一节中创建的 Python 文件。
$ nano app.py
将以下内容添加到文件中,并使用 + 然后保存文件。CTRLXENTER
class User(Document):
name = StringField(required=True)
email = EmailField(required=True)
age = IntField(required=True)
def __repr__(self):
return f'<User name="{self.name}">'
上面的代码创建了一个名为继承自 MongoEngine 模块中的类的文档类。它将 Python 类映射到数据库中的集合。默认情况下,它使用转换为蛇大小写的 Python 类名作为集合名称。此文档类使用固定架构,其中对象只能包含名称、电子邮件和期限。User
Document
六、执行 CRUD 操作
MongoEngine 将每个文档类映射到数据库中的集合。创建文档类的新实例以在集合中创建新文档。本节介绍如何使用上一节中创建的文档类执行 CRUD 操作。
进入Python控制台。
$ python
导入所需的模块。
>>> from app import User
上面的命令从您在上一节中创建的 Python 文件中导入类。User
创建新条目。
>>> user1 = User(name='Example User', email=f'user@example.com', age=21)
>>> user1.save()
上面的命令从类创建一个新对象并调用该方法,该方法启动集合并在数据库中创建新文档。User
save()
阅读第一个条目。
>>> User.objects.first()
上面的命令返回一个字典,其中包含存储在集合中的第一个文档的值。user
更新条目。
>>> user1.age = 22
>>> user1.save()
上面的命令更改对象中 age 属性的值并调用该方法,该方法将更新数据库中的文档。user1
save()
验证更改。
>>> User.objects.first().age
删除条目。
>>> user1.delete()
验证更改。
>>> User.objects
退出 Python 控制台。
>>> exit()
七、查询筛选后的数据
文档类具有允许访问存储在集合中的对象的属性。该属性是一个接受条件并返回包含筛选的文档对象的对象。本节介绍使用文档类查询筛选数据的基础知识。objects
objects
QuerySetManager
QuerySet
进入Python控制台。
$ python
导入所需的模块。
>>> from app import User
填充数据库。
>>> user_objects = [User(name=f'Person {i}', email=f'person{i}@example.com', age=i+18) for i in range(10)]
>>> User.objects.insert(user_objects)
上述命令使用枚举值创建 10 个不同对象的列表,并将其插入到数据库中。User
使用单个条件查询文档。
>>> User.objects(age__gt=20)
上面的命令返回年龄超过 20 的文档列表。
输出
[<User name="Person 3">, <User name="Person 4">, <User name="Person 5">, <User name="Person 6">, <User name="Person 7">, <User name="Person 8">, <User name="Person 9">]
使用多个条件查询文档。
>>> User.objects(age__gt=20, age__lt=25)
上面的命令返回年龄大于 20 且小于 25 的文档列表。
输出
[<User name="Person 3">, <User name="Person 4">, <User name="Person 5">, <User name="Person 6">]
获取单个文档。
>>> User.objects(age__=19).first()
上面的命令返回一个生存期为 19 的文档对象。该方法返回单个文档对象,而不是包含文档对象的列表。first()
输出
<User name="Person 1">
退出 Python 控制台。
>>> exit()
请参阅 MongoEngine 文档中的查询数据库,以查找 中的所有可用过滤选项。QuerySetManager
八、文档参考
MongoEngine ODM允许链接到文档架构中的其他文档。它使您能够在文档之间创建关系;与传统的关系数据库系统一样,它们将链接行的主键存储为外键。
您可以使用文档架构中的字段对象链接到其他文档。MongoEngine ODM 还支持 和 字段对象的组合以形成多对一关系。ReferenceField
ListField
ReferenceField
本节介绍如何使用文档类中的字段对象链接到不同的文档。ReferenceField
编辑 Python 文件。
$ nano app.py
将以下内容添加到 User
文档类上方的文件中,并使用 + 然后保存文件。CTRLXENTER
class Video(Document):
title = StringField(required=True)
def __repr__(self):
return f'<Video title="{self.title}">'
class Course(Document):
name = StringField(required=True)
price = IntField(required=True)
videos = ListField(ReferenceField(Video))
def __repr__(self):
return f'<Course name="{self.name}">'
上面的代码创建 Python 类,并从在数据库中创建两个新集合的类继承。文档类使用 and 字段对象在 videos 属性中存储视频对象引用的列表。Video
Course
Document
Course
ReferenceField
ListField
进入 Python 控制台。
$ python
导入所需的模块。
>>> from app import Course, Video
上面的命令从文件中导入 and 类。Course
Video
app.py
在视频集合中创建新条目。
>>> video1 = Video(title='Example Video 1').save()
>>> video2 = Video(title='Example Video 2').save()
上述命令创建文档类的两个新实例,该实例在数据库中启动并创建两个新文档。Video
在课程集合中创建新条目。
>>> course1 = Course(name='Example Course 1', price=100, videos=[video1, video2]).save()
上面的命令创建文档类的新实例,该实例初始化并在数据库中创建新文档。它将文档与视频集合中的其他两个文档链接。Course
验证更改。
>>> Course.objects.first().videos
>>> Course.objects.first().videos[0].title
>>> Course.objects.first().videos[1].title
退出 Python 控制台。
>>> exit()
九、文档迁移
NoSQL 数据库的灵活性使您可以轻松地进行文档架构更改。本节介绍如何在文档架构中进行结构更改。
编辑 Python 文件
$ nano app.py
将以下内容添加到文件中,并使用 + 然后保存文件。CTRLXENTER
class User(Document):
name = StringField(required=True)
email = EmailField(required=True)
age = IntField(required=True)
enrolled_courses = ListField(ReferenceField(Course))
def __repr__(self):
return f'<User name="{self.name}">'
上面的代码修改在用户集合中添加了一个名为 enrolled_courses 的新属性。和字段对象的组合允许用户文档引用多个课程文档。ListField
ReferenceField
进入Python控制台。
$ python
导入所需的模块。
>>> from app import User, Course
上面的命令从文件中导入 and 类。User
Course
app.py
获取文档对象。
>>> user1 = User.objects.first()
>>> course1 = Course.objects.first()
上述命令从用户和课程集合中获取第一个文档对象。
更新用户文档对象。
>>> user1.enrolled_courses = [course1]
>>> user1.save()
上述命令将 enrolled_courses 属性的值设置为包含文档引用对象的 Python 列表。Course
验证更改。
>>> User.objects.first().enrolled_courses
>>> User.objects.first().enrolled_courses[0].name
退出 Python 控制台。
>>> exit()
文档架构中的更改不会影响现有文档。如果要将更改应用于所有文档,则必须对集合使用该方法。有关更多信息,请参阅 MongoEngine 文档中的文档迁移部分。update_many()
十、文档元选项
文档类中的字典允许您向集合添加元数据,例如集合名称、文档索引列表、默认排序和继承选项、分片键等。本节介绍字典在文档类中的用法。meta
meta
编辑 Python 文件
$ nano app.py
将以下内容添加到 User
文档类下面的文件中,并使用 + then 保存文件。CTRLXENTER
class MetaExample(Document):
age = IntField()
meta = {
'collection': 'example_collection',
'indexes': ['age']
}
def __repr__(self):
return f'<MetaExample age={self.age}>'
上面的代码创建了一个名为从该类继承的新 Python 类。它会创建一个名为 example_collection 的新集合,并在集合索引中添加年龄字段。MetaExample
Document
索引是一种特殊的数据结构,它存储存储在数据库中的数据子集,使数据更易于以编程方式横向。如果没有索引,服务器必须执行完全集合扫描。如果查询存在适当的索引,则服务器可以限制必须扫描的文档数。
进入Python控制台。
$ python
导入所需的模块。
>>> from app import client, MetaExample
上面的命令从文件中导入对象和类。client
MetaExample
app.py
初始化集合。
>>> MetaExample(age=999).save()
验证自定义集合名称。
>>> client.get_database('mongoengine_demo').list_collection_names()
验证集合索引。
>>> MetaExample.list_indexes()
退出 Python 控制台。
>>> exit()
请参阅 MongoEngine 文档中的文档集合部分,以查找可用元选项的完整列表。
十一、结论
您安装了 MongoEngine 库,与 MongoDB 数据库服务器建立了连接,定义了文档架构,执行了 CRUD 操作,并从数据库中查询了过滤的数据。您还探索了文档引用、迁移和元选项的基础知识。