挑战30天学完Python:Day27 MongoDB数据库操作

🎉 本系列为Python基础学习,原稿来源于 30-Days-Of-Python 英文项目,大奇主要是对其本地化翻译、逐条验证和补充,想通过30天完成正儿八经的系统化实践。此系列适合零基础同学,或仅了解Python一点知识,但又没有系统学习的使用者。总之如果你想提升自己的Python技能,欢迎加入《挑战30天学完Python》

👨‍💻 作者:大奇 MegaQi
✍️ 专注测试开发实战&车载方向干货分享,欢迎访问长期关注博客和公众号。

Python操作数据库

Python是一种后端技术,它可以连接到不同的数据库应用程序。它可以连接到SQL和noSQL数据库。

MongoDB

MongoDB是一个非关系型数据库。MongoDB将数据存储在类似JSON文档中,这使得MongoDB非常灵活和可扩展。让我们看看SQL和NoSQL数据库的不同术语。下表展示说明SQL和NoSQL数据库之间的区别。

SQL VS NoSQL

在这里插入图片描述

在本篇中,我们将关注NoSQL数据库中的MongoDB。让我们在mongoDB上注册或登录(如果你已经有账号)。

在这里插入图片描述

如果你是一个新用户,在进入云服务主页后可以点击“Build a Database” 创建一个用于学习目的的在线数据库

在这里插入图片描述

选择免费服务类型,选择地区,并给定一个服务名称

在这里插入图片描述

现在,创建了一个免费的空间。创建新的空间服务可能会需要一定时间部署。

在这里插入图片描述

添加一个直连IP地址 “Add Your Current IP address”

在这里插入图片描述

添加一个账户密码,首个将作为管理员账号,请牢记。再次添加时候会可以选择用户权限。

在这里插入图片描述

以上两个创建成功后,点击“Choose a connection method”进入下一步

在这里插入图片描述

选择驱动版本 Python 3.6 or later,本复制连接到粘贴板或者本地文件中备用。

在这里插入图片描述

取得连接字符串(MongoDB URI)

刚才拷贝的连接字符串类似,它将是你Python程序连接的MongoDB的URL,但请注意账号密码要替换成你自己刚才创建的。

mongodb+srv://MegaQi:<password>@30dayofpython.nax3k0s.mongodb.net/?retryWrites=true&w=majority

Python需要一个mongoDB驱动程序来访问mongoDB数据库。我们将使用 pymongo 模块 将我们应用程序与mongoDB连接起来。在你的项目目录中首先你需要安装pymongo和dnspython。

pip install pymongo

连接尝试

出于可能出现国内网络原因,如果你连接云服务有问题,可以下载安装包本地装一个MongoDB方便学习测试。

下载地址:ww.mongodb.com/download-center/community

在这里插入图片描述

使用 pymongo 对数据进行连接(以下均为本地数据演示)

import pymongo
# client = pymongo.MongoClient("mongodb+srv://MegaQi:YourPassword@30dayofpython.dhy8xao.mongodb.net/?retryWrites=true&w=majority")
client = pymongo.MongoClient("mongodb://localhost:27017/") # 注意,本地mongo数据库安装完后默认是没有用户密码的可直连
print(client.list_database_names())

当我们运行上面的代码时,我们得到默认的mongoDB数据库。

['admin', 'config', 'local']

如果你是一个完整安装,你的电脑里还有个桌面客户端compass用于连接数据。

在这里插入图片描述

创建数据库和集合

让我们创建一个名为 thirty_days_of_python 数据库和 students 集合。

要创建一个数据库可以选择以下两种方式中一种

db = client.name_of_databse
# 或
db = client['name_of_database']

在如下代码中在创建数据的同时,通过db.collection.insert_one 再插入一条数据,这样数据就会被成功创建。

import pymongo
# client = pymongo.MongoClient("mongodb+srv://MegaQi:YourPassword@30dayofpython.dhy8xao.mongodb.net/?retryWrites=true&w=majority")
client = pymongo.MongoClient("mongodb://localhost:27017/")
print(client.list_database_names())

db = client.thirty_days_of_python

db.students.insert_one({'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai', 'age': 18})
print(client.list_database_names())

现在,已经创建了数据库 thirty_days_of_pythonstudents 的集合。当我们再次检查数据库列表的时候就会发现新增的 thirty_days_of_python 数据了。

['admin', 'config', 'local', 'thirty_days_of_python']

这时你可以通过云服务Collections或本地客户端查看最新的数据,如果存在students说明,数据库和文档都成功创建了。

在这里插入图片描述

从图中可以看出,创建文档时使用了一个长id,该id为主键。每次我们创建一个文档,mongoDB都会为它创建一个唯一的id。

多行数据插入

上述方法 insert_one() 每次仅插入一项,如果我们想一次插入多条数据,可以使用 insert_many() 方法或for循环。

例子1:我们可以使用for循环一次插入多个文档。

students = [
        {'name':'David','country':'UK','city':'London','age':34},
        {'name':'John','country':'Sweden','city':'Stockholm','age':28},
    ]
for student in students:
    db.students.insert_one(student)

例子2:使用 insert_many 以此插入多条。

students2 = [
        {'name':'Sami','country':'Finland','city':'Helsinki','age':25},
        {'name':'Tom','country':'Kroen','city':'Seoul','age':26},
    ]
db.students.insert_many(students2)

当执行这块代码无异常后,查看数据结果如下:

在这里插入图片描述

MongoDB查找

关于文档查找,可以使用 find()find_one() 方法,这两是mongoDB数据库中查找集合数据的常用方法。它类似于MySQL数据库中的SELECT语句。

让我们先使用 find_one() 方法来获取数据库集合中的文档,如果有符合条件的多条,默认返回第一条。

  • *find_one({“_id”: ObjectId(“id”})
student_one = db.students.find_one()  #不指定条件则默认返回默认排序第一条
print(student_one)

{'_id': ObjectId('64295174e77a296584fc6660'), 'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai', 'age': 18}

上面的查询返回第一个条目,但是我们可以使用特定的_id针对特定的文档。举个例子,用David的id获取David对象。

  • ‘_id’:ObjectId(‘64296b238e322f5f0a57da4b’)
from bson.objectid import ObjectId # ID需要使用ObjectId对象

student_with_id = db.students.find_one({'_id':ObjectId('64296b238e322f5f0a57da4b')})
print(student_with_id)
{'_id': ObjectId('64296b238e322f5f0a57da4b'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}

我们已经通过上面的例子看到了如何使用 find_one()。让我们来看看如何使用 find()

  • find(): 如果不传递查询对象,则返回集合中的所有数据。
import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")

db = client['thirty_days_of_python'] # 换一种访问数据库的方式
students = db.students.find()
for student in students:
    print(student)
{'_id': ObjectId('64295174e77a296584fc6660'), 'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai', 'age': 18}
{'_id': ObjectId('64296b238e322f5f0a57da4a'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('64296b238e322f5f0a57da4b'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('64296c03dcde19198344b720'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
{'_id': ObjectId('64296c03dcde19198344b721'), 'name': 'Tom', 'country': 'Kroen', 'city': 'Seoul', 'age': 26}

我们可以通过在 find({},{}) 中传递第二个对象来指定要返回的字段。0表示不包含,1表示包含。

students = db.students.find({}, {"_id":0,  "name": 1, "country":1})
for student in students:
    print(student)

仅仅返回了指定显示的name和country字段

{'name': 'MegaQi', 'country': 'China'}
{'name': 'David', 'country': 'UK'}
{'name': 'John', 'country': 'Sweden'}
{'name': 'Sami', 'country': 'Finland'}
{'name': 'Tom', 'country': 'Kroen'}

条件查找

在mongoDB想要通过条件进行查找。我们可以传递一个查询对象实现对文档的过滤。

query = {
    "country":"Finland"
}
students = db.students.find(query)

for student in students:
    print(student)

指定国家为 Finland 条件

{'_id': ObjectId('64296c03dcde19198344b720'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}

多条件查询

query = {
    "country":"China",
    "city":"ShangHai"
}
students = db.students.find(query,{"_id":0,  "name": 1, "country":1, "city":1})
for student in students:
    print(student)
{'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai'}

带有修饰符的查询

query = {"age":{"$gt":27}} # $gt 表示大于
students = db.students.find(query)
for student in students:
    print(student)
{'_id': ObjectId('64296b238e322f5f0a57da4a'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('64296b238e322f5f0a57da4b'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}

其他一些条件符号常用的还有:

  • $eq = (等于)
  • $gt > (大于)
  • $gte >= (大于等于)
  • $lt < (小于)
  • $lte <= (小于等于)
  • $ne != (不等于)
  • $in in (in)
  • $nin !in (not in)

限制返回数量

可以使用 limit() 方法限制返回的文档数量。同mysql中的limit语法。

student_limit_three = db.students.find().limit(3)
for student in student_limit_three:
    print(student)

所有查询数据的前三条

{'_id': ObjectId('64295174e77a296584fc6660'), 'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai', 'age': 18}
{'_id': ObjectId('64296b238e322f5f0a57da4a'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('64296b238e322f5f0a57da4b'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}

排序查询

默认情况下,排序是升序的。我们可以通过添加-1参数将排序改为降序。

students = db.students.find().sort('name')
print(">>>姓名正序:")
for student in students:
    print(student)


students = db.students.find().sort('name',-1)
print(">>>姓名倒序:")
for student in students:
    print(student)

students = db.students.find({},{"_id":0, "age": 1, "name": 1, "country":1, "city":1}).sort('age')
print(">>>姓名小到大:")
for student in students:
    print(student)

students = db.students.find({},{"_id":0, "age": 1, "name": 1, "country":1, "city":1}).sort('age',-1)
print(">>>年龄大到小:")
for student in students:
    print(student)

Ascending order

>>>姓名正序:
>>>姓名正序:
{'_id': ObjectId('64296b238e322f5f0a57da4a'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('64296b238e322f5f0a57da4b'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('64295174e77a296584fc6660'), 'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai', 'age': 18}
{'_id': ObjectId('64296c03dcde19198344b720'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
{'_id': ObjectId('64296c03dcde19198344b721'), 'name': 'Tom', 'country': 'Kroen', 'city': 'Seoul', 'age': 26}
>>>姓名倒序:
{'_id': ObjectId('64296c03dcde19198344b721'), 'name': 'Tom', 'country': 'Kroen', 'city': 'Seoul', 'age': 26}
{'_id': ObjectId('64296c03dcde19198344b720'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
{'_id': ObjectId('64295174e77a296584fc6660'), 'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai', 'age': 18}
{'_id': ObjectId('64296b238e322f5f0a57da4b'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('64296b238e322f5f0a57da4a'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
>>>姓名小到大:
{'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai', 'age': 18}
{'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
{'name': 'Tom', 'country': 'Kroen', 'city': 'Seoul', 'age': 26}
{'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
>>>年龄大到小:
{'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'name': 'Tom', 'country': 'Kroen', 'city': 'Seoul', 'age': 26}
{'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
{'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai', 'age': 18}

查询更新

我们将使用 update_one() 方法来更新一项数据。它需要两个对象,一个是查询对象,另一个是新的对象。

import pymongo
from bson.objectid import ObjectId
# client = pymongo.MongoClient("mongodb+srv://MegaQi:YourPassword@30dayofpython.dhy8xao.mongodb.net/?retryWrites=true&w=majority")
client = pymongo.MongoClient("mongodb://localhost:27017/")

db = client['thirty_days_of_python']

query = {'age':34}
new_value = {'$set':{'age':22}}
db.students.update_one(query, new_value)

for student in db.students.find():
    print(student)
{'_id': ObjectId('64295174e77a296584fc6660'), 'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai', 'age': 18}
{'_id': ObjectId('64296b238e322f5f0a57da4a'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 22}
{'_id': ObjectId('64296b238e322f5f0a57da4b'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('64296c03dcde19198344b720'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
{'_id': ObjectId('64296c03dcde19198344b721'), 'name': 'Tom', 'country': 'Kroen', 'city': 'Seoul', 'age': 26}

当我们想要批量更改文档数据时,可以使用 upate_many() 方法。

删除文档数据

方法 delete_one() 用于删除一个文档。delete_one() 需要一个查询对象参数。它只会删除第一个符合条件的文档。

让我们从集合中删除一个名为John的文档。

query = {'name':'John'}
db.students.delete_one(query)
for student in db.students.find():
    print(student)

数据减少了一条,John的文档信息被移除了。

{'_id': ObjectId('64295174e77a296584fc6660'), 'name': 'MegaQi', 'country': 'China', 'city': 'ShangHai', 'age': 18}
{'_id': ObjectId('64296b238e322f5f0a57da4a'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 22}
{'_id': ObjectId('64296c03dcde19198344b720'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
{'_id': ObjectId('64296c03dcde19198344b721'), 'name': 'Tom', 'country': 'Kroen', 'city': 'Seoul', 'age': 26}

同样,当我们向做批量删除的时候,可以使用 delete_many() 方法,它也需要一个查询对象。另外如果想直接清空这个文档,可以将查询条件置为空,即 delete_many({})

删除集合

我们可以使用 drop() 方法从数据里直接删除一个集合。

db.students.drop()

for student in db.students.find():
    print(student)

现在我们已经将学生文档集从数据中删除掉了。再次查询打印将输出的是空的结果。

以上是对于数据库MongoDB的一些基本用法。

本篇没有额外的作业,大家只需要按需了解文档数据库MongoDB的云(或本地)服务使用,及基本的语法即可。

🎉 CONGRATULATIONS ! 🎉

<< 上一篇 Day 26 | 下一篇 Day 28 >>

github 项目(含参考答案)地址:https://github.com/QiCodeCN/30-Days-Of-Python-zh_CN
如喜欢通过“点赞👍收藏❤️关注➕”鼓励作者大奇
文章中如有错误或疑问欢迎指正和交流。

  • 21
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mega Qi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值