目录
在我们的《MongoDB定义指南》中,我们涵盖了很多基础。在这里,您可以获得有关NoSQL 数据库,它们是什么,如何使用它们以及使用它们的好处的更多信息。除此之外,您还可以找到有关不同类型的NoSQL数据库及其最受欢迎的代表的更多信息。这些类型之一是所谓的Document NoSQL数据库,它们最受欢迎的代表是MongoDB。
因此,我们继续介绍了该数据库的一些基础 。在那里,您可以学习如何安装MongoDB,创建数据库、集合、文档以及如何使用这些实体。另外,还有许多有关MongoDB 部署、分片、副本集以及如何操作它们的信息。您也可以找到如何在.NET环境、JavaScript MEAN框架和无服务器 环境中使用此数据库。因此,我们希望以此为基础,并写一篇文章,介绍如何在Python中使用MongoDB 。
在本文中,我们实现了一个存储库,您可以使用该存储库来处理Users组中的数据。我们在.NET的《MongoDB定义指南》中做了类似的事情。实际上,我们提出了两种实现方法,即,使用两个Python模块——PyMongo和MongoEngine。第一个库PyMongo的实现是低级别的实现,而MongoEngine的实现可以看作是更高级别的实现。但是,在深入了解每个实现的细节之前,让我们先安装MongoDB和两个Python模块。
先决条件
MongoDB是免费和开源的。可以从这里下载。获取版本和您的操作系统之后。在这个例子中,我们为Windows系统使用MongoDB的4.2.1社区服务器。
安装后,用户可以使用以下命令运行MongoDB 服务器:
mongod –dbpath PATH_TO_THE_DIR
通过此安装,还将安装MongoCompass。这是可视化的GUI 组件,您可以使用它来操纵数据库、集合和文档:
就这些示例而言,我们使用本地数据库和用户集合:
正如我们提到的,您将需要两个Python 模块,因此让我们安装它们。首先,您可以像这样安装PyMongo:
pip install pymongo
之后安装MongoEngine:
pip install mongoengine
就是这样。我们已准备好实现。
PyMongo实现
让我们实现使用PyMongo 模块的UserRepository类。更准确地说,我们只需要该模块中的一个类——MongoClient:
from pymongo import MongoClient
class UserRepository(object):
def __init__(self):
mongoclient = MongoClient('localhost', 27017)
#mongoclient = MongoClient('mongodb://localhost:27017')
database = mongoclient.local
self._users = database.user
现在,我们可以创建此类的对象,如下所示:
user_repo = UserRepository()
创建操作
接下来,我们实现创建 操作。我们添加了两个方法:insert和insert_many。第一种方法仅将一个用户添加到集合中,而另一种方法从提供的array中添加所有用户。我们可以看到,下面他们只是从PyMongo中利用函数insert_one和insert_many。
class UserRepository(object):
def __init__(self):
mongoclient = MongoClient('localhost', 27017)
#mongoclient = MongoClient('mongodb://localhost:27017')
database = mongoclient.local
self._users = database.user
# Create operations
def insert(self, user):
return self._users.insert_one(user)
def insert_many(self, users):
return self._users.insert_many(users)
现在,我们可以从对象中使用这些功能。方法insert可以这样使用:
user = {
'name':"Rubik",
'age':33,
'blog':"rubikscode.net"
}
result = user_repo.insert(user)
print(result.acknowledged)
当我们使用MongoDB Compass peek此集合时,我们可以看到该文档是在用户集合中创建的。
而insert_many可以这样使用:
user_1 = {
'name':"Vanja",
'age':29,
'blog':"eventroom.org"
}
user_2 = {
'name':"Marko",
'age':36,
'blog':"rubikscode.net"
}
result = user_repo.insert_many([user_1, user_2])
print(result.acknowledged)
再次使用MongoDB Compass检查此操作的结果:
读取操作
太酷了,现在我们可以将文档添加到集合中了,让我们实现能够检索此信息的函数。我们添加了三个新函数:read_all,read_many和read。函数read_all 返回集合中的所有文档。方法read和read_many相似,它们都接受某种条件。但是,第一个仅返回一个满足条件的文档,而其他则返回所有满足条件的文档。
class UserRepository(object):
def __init__(self):
mongoclient = MongoClient('localhost', 27017)
#mongoclient = MongoClient('mongodb://localhost:27017')
database = mongoclient.local
self._users = database.user
# Create operations
def insert(self, user):
return self._users.insert_one(user)
def insert_many(self, users):
return self._users.insert_many(users)
# Read operations
def read_all(self):
return self._users.find()
def read_many(self, conditions):
return self._users.find(conditions)
def read(self, conditions):
return self._users.find_one(conditions)
这些函数可以这样使用 :
print("---Read All---")
all_users = user_repo.read_all()
for user in all_users:
print(user)
print("--------------\n")
print("---Read Many--")
rc_users = user_repo.read_many({'blog':'rubikscode.net'})
for user in rc_users:
print(user)
print("--------------\n")
print("--- Read ---")
one_rc_user = user_repo.read({'blog':'rubikscode.net'})
print(one_rc_user)
print("--------------\n")
而输出是这样的:
—Read All—
{‘_id’: ObjectId(‘5dbad5a4dde338d6e1cd3ea7’), ‘name’: ‘Rubik’, ‘age’: 33, ‘blog’: ‘rubikscode.net’}
{‘_id’: ObjectId(‘5dbc2f46ac3310f0215ba277’), ‘name’: ‘Vanja’, ‘age’: 29, ‘blog’: ‘eventroom.org’}
{‘_id’: ObjectId(‘5dbc2f46ac3310f0215ba278’), ‘name’: ‘Marko’, ‘age’: 36, ‘blog’: ‘rubikscode.net’}
————–
—Read Many–
{‘_id’: ObjectId(‘5dbad5a4dde338d6e1cd3ea7’), ‘name’: ‘Rubik’, ‘age’: 33, ‘blog’: ‘rubikscode.net’}
{‘_id’: ObjectId(‘5dbc2f46ac3310f0215ba278’), ‘name’: ‘Marko’, ‘age’: 36, ‘blog’: ‘rubikscode.net’}
————–
— Read —
{‘_id’: ObjectId(‘5dbad5a4dde338d6e1cd3ea7’), ‘name’: ‘Rubik’, ‘age’: 33, ‘blog’: ‘rubikscode.net’}
————–
更新操作
我们实现了两种更新方法:update和gain_age。第一个目的是演示如何使用条件更新单个文档。另一个功能演示如何将MongoDB更新修饰符封装在函数中,并根据需要定制存储库。可以说,这是这种方法的最大优势。
class UserRepository(object):
def __init__(self):
mongoclient = MongoClient('localhost', 27017)
#mongoclient = MongoClient('mongodb://localhost:27017')
database = mongoclient.local
self._users = database.user
# Create operations
def insert(self, user):
return self._users.insert_one(user)
def insert_many(self, users):
return self._users.insert_many(users)
# Read operations
def read_all(self):
return self._users.find()
def read_many(self, conditions):
return self._users.find(conditions)
def read(self, conditions):
return self._users.find_one(conditions)
# Update operations
def update(self, conditions, new_value):
return self._users.update_one(conditions, new_value)
def increment_age(self, conditions):
return self._users.update_one(conditions, {'$inc' : {'age' : 1}})
函数update可用于更新文档名称,如下所示:
result = user_repo.update({'name':'Rubik'}, {'$set': {'name': "Nikola"}})
print(result.acknowledged)
该结果是这样的:
方法 crement_age 更易于使用:
result = user_repo.increment_age({'name':'Nikola'})
print(result.acknowledged)
结果可以在MongoDB Compass中观察到:
删除操作
就像我们可以一次创建一个或多个文档一样,我们可以删除一个或多个文档。这使用两个函数完成:delete和delete_many。这两个函数均接收删除条件。以下是UserRepository类的最终形式:
class UserRepository(object):
def __init__(self):
mongoclient = MongoClient('localhost', 27017)
#mongoclient = MongoClient('mongodb://localhost:27017')
database = mongoclient.local
self._users = database.user
# Create operations
def insert(self, user):
return self._users.insert_one(user)
def insert_many(self, users):
return self._users.insert_many(users)
# Read operations
def read_all(self):
return self._users.find()
def read_many(self, conditions):
return self._users.find(conditions)
def read(self, conditions):
return self._users.find_one(conditions)
# Update operations
def update(self, conditions, new_value):
return self._users.update_one(conditions, new_value)
def increment_age(self, conditions):
return self._users.update_one(conditions, {'$inc' : {'age' : 1}})
# Delete operations
def delete(self, condition):
return self._users.delete_one(condition)
def delete_many(self, condition):
return self._users.delete_many(condition)
如果要删除一个文档,可以这样操作:
result = user_repo.delete({'name':'Nikola'})
print(result.acknowledged)
该操作的结果:
在演示删除多个文档的样子之前,我们添加一个刚删除的文档并以先前状态还原集合:
如果在此之后,我们调用delete_many,则如下所示:
result = user_repo.delete_many({'blog':'rubikscode.net'})
print(result.acknowledged)
操作结果:
MongoEngine实现
如您所见,使用PyMongo实现存储库非常容易且有趣。但是,许多用户并不需要深入到这种低层次的抽象。这就是为什么有些人选择使用在PyMongo——MongoEngine之上构建库的原因。本质上,MongoEngine 是ODM,即,对象文档映射器。就像我们有关系数据库的ORM 一样,对于文档NoSQL数据库,我们也有ODM。MongoEngine提供了所需的更高级别的抽象。因此,让我们将其导入并附加到我们的数据库中:
from mongoengine import *
connect('local', host='localhost', port=27017)
该函数的第一个参数是数据库的名称,而其他两个参数则定义location。为了“附加”到集合,我们需要实现一个类,该类描述该集合-模型的文档。这非常类似于我们在各种ORM中执行此操作的方式,因此,如果您有使用EntityFramework的经验,这对您来说自然而然的。模型类必须继承Document。 对于我们的用户集合,如下所示:
class User(Document):
name = StringField(required=True, max_length=50)
age = IntField(required=True)
blog = StringField(required=True, max_length=50)
在此模型中,我们告诉MongoEngine 我们希望用户拥有姓名,年龄 和博客。 在下面,文档 基础对象将验证提供的数据。MongoEngine提供了各种字段类型 (这里我们仅使用StringField和IntField)以及这些类型的选项 。
创建操作
当我们实现User模型类时,使用它来操作数据库对象是很容易的。这是我们如何在用户 集合中创建文档的方法:
user = User(
name = "Rubik",
age = 33,
blog = "rubikscode.net")
# Create Operation
user.save()
请注意,在这种特殊情况下,保存 方法会在用户集合中创建文档。
读取操作
读取数据也得到了简化。这是完成的过程:
read_users = User.objects
for user in User.objects:
print("Name: {}; Age: {}; Blog: {}".format(user.name, user.age, user.blog))
使用对象字段,我们可以访问数据库中的所有文档。在这种情况下,只有一个:
Name: Rubik; Age: 33; Blog: rubikscode.net
如果我们要创建各种查询,则可以在此之上使用过滤器功能。
更新操作
使用保存方法对现有对象再次进行更新。基本上,当您第一次调用save方法时,它将创建一个文档,而第二次它将对其进行更新 。
user.name = "Marko"
# Update
user.save()
结果:
删除操作
只需通过在User 对象上调用delete方法 即可执行删除操作 。
user.delete()
该结果是这样的:
结论
在本文中,我们有机会看到了如何在Python中使用MongoDB。我们可以看到它们具有相当的可比性, 并且可以很好地协同工作。我们使用了两个模块PyMongo和MongoEngine,因此根据您需要的抽象级别,可以选择最适合您的项目的一个。
来源:CSDN
作者:寒冰屋
链接:https://blog.csdn.net/mzl87/article/details/103748073