使用Python操作MongoDB

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 使用Python操作MongoDB

1 连接数据库


1.1 安装PyMongo


使用Python操作MongoDB需要使用一个第三方库——PyMongo。安装这个库与安装Python其他的第三方库一样,使用pip安装即可:


python3 -m pip install pymongo


也可以指定安装的版本:


python3 -m pip3 install pymongo==3.5.1


更新 pymongo 命令:


python3 -m pip3 install --upgrade pymongo


安装完成以后,打开Python交互环境,导入PyMongo。如果不报错(如图所示),则表示安装成功


640.png


1.2 连接数据库


要使用PyMongo操作MongoDB,首先需要初始化数据库连接。


  • (1)如果 MongoDB 就运行在本地电脑上,而且也没有修改端口或者添加用户名和密码,则初始化MongoClient的实例不需要带参数,直接写为以下格式:


import pymongo
conn = pymongo.MongoClient()


  • (2)如果MongoDB运行在其他服务器上,则需要使用“URI(UniformResource Identifier,统一资源标志符)”来指定链接地址


import pymongo
conn = pymongo.MongoClient('mongodb://test:12345@45.10.110.77:27019')


MongoDB的URI格式如下:mongodb://用户名:密码@服务器IP或域名:端口例如:


  • (3)如果没有设置权限验证,则不需要用户名和密码,可写为


import pymongo
conn = pymongo.MongoClient('mongodb://45.10.110.77:27019')


1.3 连接库与集合


PyMongo连接库与集合有两种方式


  • 方式1


连接数据库与集合的方法1


from pymongo import MongoClient
conn = MongoClient()
databae = conn.数据库名
collection = database.集合名


需要注意,在使用这种方式时,代码中的“数据库名”和“集合名”都不是变量名,它们直接就是库的名字和集合的名字。例如,要连接上example_data_1所在的集合,则Python代码如下:


from pymongo import MongoClient
conn = MongoClient()
database = conn.chapter_1
collection = database.example_data_1


  • 方式2


连接数据库与集合方法2


from pymongo import MongoClient
db_name = 'chapter_1'
collection_name = 'example_data_1'
conn = MongoClient()
database = conn[db_name]
collection = database[collection_name]


在使用这种方式时,在方括号中可以直接填变量来指定库名和集合名。当然,也可以直接填字符串,例如:


from pymongo import MongoClient
conn = MongoClient()
database = conn['chapter_1']
collection = database['example_data_1']


方式1 和方式2效果是完全相同的。大家可以任意选择一种自己喜欢的方式。


方式2主要用在需要批量操作数据库的情况下。例如在项目中,有时有多个测试环境,现在需要同时更新这些环境对应的数据库,则可以使用方式2。因为,这样可以将多个数据库的名字或者是多个集合的名字保存在列表中,然后再使用循环来进行操作,如下所示:


database_name_list = ['develop_env_alpha','develop_env_beta','develop_env_preflight']
for each_db in database_name_list:
        database = conn[each_db]
    collection = database.account
    collection.updateMany(.....)


其中第3行代码,在循环里面每次连接不同的库,这样写可以同时更新多个数据库的信息,对于同一个数据库里面的多个集合,也可以使用这个方法来操作。


注意:在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。


2 MongoDB命令在Python中的对应方法


在获取到集合连接对象collection后,就可以用这个对象的各个方法来操作MongoDB了。


虽然 MongoDB 的命令和 collection 的方法名在写法上有微小的差异,但绝大多数的MongoDB语句的参数直接复制到Python代码中都可以使用。


MongoDB的命令使用的是驼峰命名法,而PyMongo使用的是“小写字母加下划线”的方式。它们的对比见下表:


MongoDB命令 PyMongo方法
insertOne insert_one
insertMany insert_many
find find
updateone update_one
updateMany update_many
deleteOne delete_one
deleteMany delete_many


例如,Robo 3T执行的批量插入语句:


db.getCollection('example_data_1').insertMany([
     {'name': '赵小三','age':20,'address':'北京'},
   {'name': '钱小四','age':21,'address':'上海'},
   {'name': '孙小五','age':20,'address':'山东'},
   {'name': '李小六','age':23,'address':'河北'},
   {'name': '欧阳小七','age':24,'address':'杭州'}
 ])


使用Python批量插入数据,代码如下:


from pymongo import MongoClient
conn = MongoClient()
database = conn.chapter_1
collection = database.example_data_2
collection.insert_many([
   {'name': '王小二','age':21,'student':True,'address':'广州'},
   {'name': '赵小三','age':20,'student':True,'address':'北京'},
   {'name': '钱小四','age':21,'student':True,'address':'上海'},
   {'name': '孙小五','age':20,'student':True,'address':'山东'},
   {'name': '李小六','age': None,'student':True,'address':'河北'},
   {'name': '欧阳小七','age':24,'student':False,'address':'杭州'},
   {'name': '公孙小八','age':25,'student':False,'address':'广州'}
 ])


其中,第4行代码中使用了新的集合名字,用以区别。


使用Python操作MongoDB还有一个好处:如果当前使用的库或者集合不存在,则在调用了插入方法以后,PyMongo会自动创建对应的库或集合。


总之,绝大部分的操作,直接从Robo 3T中复制到Python中都可以运行,几乎不需要修改。


3 插入数据到MongoDB


基本语法


collection.insert_one(字典)  # 插入一条数据
collection.insert_many(包含字典的列表)  # 批量插入多条数据


被插入的数据格式


{'field_1': value_1, 'field_2': value_2}
[
 {'field_1': value_1, 'field_2': value_2},
 {'field_1': value_3, 'field_2': value_4}
]


说明


  • MongoDB不需要提前创建数据库、不需要提前创建集合、不需要提取定义数据格式,想插入什么数据,直接插就行。


  • 同一个集合的不同行数据,字典可以不一


举例


在Python中,将字典{'name': ’王小六’, 'age': 25, 'work': ’厨师’}插入到MongoDB中。


具体命令如下:


collection.insert_one({'name': ’王小六’, 'age': 25, 'work': ’厨师’})


提示:PyMongo还有一个通用方法——collection.insert()。


  • 如果传入的是一个字典,则collection.insert()相当于insert_one


  • 如果传入的是一个包含字典的集合,则collection.insert()相当于insert_many


但是PyMongo开发者准备移除它,因此不推荐读者在正式环境中使用这个方法。


4 从MongoDB中查询数据


查询一条数据


我们可以使用 find_one() 方法来查询集合中的一条数据,查询example_data_2 文档中的第一条数据:


from pymongo import MongoClient
db_name = 'chapter_1'
collection_name = 'example_data_1'
conn = MongoClient()
database = conn[db_name]
collection = database[collection_name]
x=collection.find_one({})
print(x)


输出结果:


640.png


查询集合中所有数据


from pymongo import MongoClient
db_name = 'chapter_1'
collection_name = 'example_data_1'
conn = MongoClient()
database = conn[db_name]
collection = database[collection_name]
collection = database.example_data_2
rows = collection.find()
for row in rows:
    print(row)


结果如下:


640.png


逻辑查询


collection.find({'字段名': {'基本符号': 边界值, '基本符号': 边界值}})


在Python中,从MongoDB中查询所有“age”大于21小于25,并且“name”不等于“夏侯小七”的记录。


collection = database.example_data_2
rows = collection.find({'age':{'$lt':25,'$gt':21},
                        'name':{'$ne':'公孙小八'}})
for row in rows:
    print(row)


运行效果如图所示:


640.png


查询并对结果进行计数


collection.find().count()


查询并对结果进行计数


# 在Python中
collection.find().sort('字段名', 方向)
# 在Robo 3T的命令输入区域
collection.find().sort({'字段名': 方向})


其中方向为1表示升序,方向为**-1**表示降序


对字段去重


# 对字段去重
handler.distinct('字段名')
# 先筛选再去重
handler.distinct('字段名', 查询条件)


注意:如果字段的数量很大,那么轻易不要在Robo 3T里面直接执行,否则可能导致Robo 3T卡死


5 更新/删除MongoDB中的数据


基本语法


# 更新一条数据
collection.update_one(查询条件, {'$set': 被更新的数据})
# 更新所有满足要求的数据
collection.update_many(查询条件, {'$set': 被更新的数据})


被更新的数据


{'field_1': value_1, 'field_2': value_2}


举例


在Python中更新数据和删除数据:


  • (1)对于“name”为“公孙小八”的记录,将“age”更新为80,将“address”更新为“美国”。
  • (2)删除“age”为0的数据


1.更新MongoDB中的数据


在Python中,可以使用udate_many方法来批量更新数据


collection.update_many(
    {'name': '公孙小八'},
    {'$set': {'address': '英国','age':80}})


更新操作还支持一个“upsert”参数。该参数的作用是:如果数据存在,则更新;如果数据不存在,则创建。


例如,对于“name”为“隐身人”的记录,将“age”改为0,将“address”改为“里世界”


由于example_data_1中没有这一条记录,因此直接更新会报错,如图所示。


result = collection.update_one({'name':'隐身人'},
                               {'$set':{'name':'隐身人',
                                        'age': 0,
                                        'address':'里世界'}})
print(list(result))


640.png


加上“upsert”参数,看看效果


result = collection.update_one({'name':'隐身人'},
                               {'$set':{'name':'隐身人',
                                        'age': 0,
                                        'address':'里世界'}},
                                upsert = True)
print(result)


640.png


提示:如果打开了更新或插入功能,则“$set”的值是完整的文档内容,应该包含每一个字段,而不仅仅是需要被更新的字段,否则被插入的内容只有被更新的这几个字段。


2.删除MongoDB中的数据


基本语法


# 删除第一个满足条件的数据
collection.delete_one(查询条件)
# 删除所有满足条件的数据
collection.delete_many(查询条件)


删除“age”为0的数据。删除语句如下:


collection.delete_many({'age': 0})


建议先写查询语句,确认查询出来的数据就是自己想删除的数据,然后把关键字find改为delete_one或者delete_many


6 MongoDB与Python不通用的操作


绝大部分情况下,MongoDB中的命令参数直接复制到Python中就可以使用,但有一些情况例外。假设数据集example_data_2如图所示:


640.png


6.1 空值


在MongoDB中,空值写作null,在Python中,空值写作None。


MongoDB不认识None,Python不认识null。


为了从数据集example_data_2中查询出所有“age”字段为空的数据,在Robo 3T中的查询语句为:


db.getCollection('example_data_2').find({'age': null})


运行结果如图所示:


640.png


如果直接把这段查询语句中的参数搬到Python中运行,则会导致报错,如图所示:


640.png


Python会把null当作一个普通的变量,但是这个变量又没有定义,所以导致报错。


在 Python 中,要查询空值需要使用 None,对上述代码做一些修改——把“null”改为“None”,则查询成功,如图所示:


640.png


6.2 布尔值


布尔值就是“真”和“假”两个值。在MongoDB中,“真”为true,“假”为false,首字母小写;在Python中,“真”为True,“假”为False,首字母大写。


在MongoDB中,查询所有student为true的记录,如图所示:


640.png


如果把这段查询语句的参数直接复制到 Python 中,同样也会导致报错,因为 Python 会把true当作一个普通的变量,如图所示:


640.png


把true改为True,则查询成功,如图所示:


640.png


6.3 排序参数


对查询到的结果进行排序是一个常见操作,在MongoDB中,sort()命令接收一个参数,这个参数是一个字典,Key是被排序的字段名,值为1或者−1。


对于数据集example_data_2,在Robo 3T中对“age”字段进行倒序排列,如图所示:


640.png


但在Python中,查询结果的sort()方法如果使用MongoDB的写法则会报错,如图所示:


640.png


在Python中,sort()方法接收两个参数:第1个参数为字段名,第2个参数为-1或者1。就能够正常运行,如图所示:


640.png


6.4 查询_id


在Robo 3T中,可以根据_id的值来查询文档。此时查询语句如下:


640.png


在安装PyMongo的同时,Python会自动安装一个叫作“bson”的第三方库。ObjectId这个类需要从bson库中导入,具体命令如下:


from bson import ObjectId
collection.find({'_id': ObjectId('5e8ac5dfdd9cf99b7a446e99')})


运行结果如下:


640.png

小结


本文首先介绍了MongoDB的安装,然后介绍了MongoDB的图形化操作软件Robo 3T。


通过Robo 3T的命令输入窗口输入命令,可实现对MongoDB数据库的增、删、改、查操作。


MongoDB的大部分操作都可以平滑移植到Python中。因此,大多数情况下,直接把Robo 3T中的MongoDB操作语句复制到Python中就能使用。当然,有很小一部分情况例外。

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
3月前
|
NoSQL MongoDB 数据库
python3操作MongoDB的crud以及聚合案例,代码可直接运行(python经典编程案例)
这篇文章提供了使用Python操作MongoDB数据库进行CRUD(创建、读取、更新、删除)操作的详细代码示例,以及如何执行聚合查询的案例。
41 6
|
3月前
|
NoSQL JavaScript Java
Java Python访问MongoDB
Java Python访问MongoDB
26 4
|
5月前
|
存储 监控 数据处理
💻Python高手必备!文件系统操作秘籍,让你的数据存取如臂使指
【7月更文挑战第29天】在数据驱动时代, Python以简洁语法、丰富库生态和强大跨平台能力, 成为数据科学等领域首选。本文探讨Python文件系统操作秘籍, 助力高效数据处理。
56 11
|
5月前
|
索引 Python
Python的列表操作有哪些?
Python的列表操作非常丰富,包括列表的创建、元素的访问、修改、添加、删除、切片、排序等多个方面。
54 12
|
5月前
|
监控 网络协议 网络安全
SMTP操作使用详解并通过python进行smtp邮件发送示例
SMTP操作使用详解并通过python进行smtp邮件发送示例
166 3
|
5月前
|
数据挖掘 数据处理 Python
🔍深入Python系统编程腹地:文件系统操作与I/O管理,打造高效数据处理流水线
【7月更文挑战第29天】深入Python系统编程腹地:文件系统操作与I/O管理,打造高效数据处理流水线
43 3
|
5月前
|
安全 数据安全/隐私保护 Python
|
5月前
|
Serverless 语音技术 开发工具
函数计算操作报错合集之怎么何集成nls tts python sdk
在使用函数计算服务(如阿里云函数计算)时,用户可能会遇到多种错误场景。以下是一些常见的操作报错及其可能的原因和解决方法,包括但不限于:1. 函数部署失败、2. 函数执行超时、3. 资源不足错误、4. 权限与访问错误、5. 依赖问题、6. 网络配置错误、7. 触发器配置错误、8. 日志与监控问题。
|
5月前
|
API Python
Python高手修炼手册:精通文件系统操作,掌控I/O管理,提升编程效率
【7月更文挑战第30天】在 Python 编程中, 文件系统操作与 I/O 管理是连接程序与数据的关键。初学者常因路径错误和权限问题受挫, 而高手能自如管理文件。传统 `os` 和 `os.path` 模块易出错, `pathlib` 提供了更直观的对象导向 API。I/O 方面, 同步操作会阻塞程序, 异步 (如使用 `aiofiles`) 则能大幅提升并发能力。真正的高手不仅掌握 API, 更能预见性能瓶颈并优化代码, 实现高效与优雅。
48 1