Python / 28 使用 Python 操作 Mongo 数据库

1. 简介

MongoDB 是一个基于分布式文件存储的数据库,旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,它支持的查询语言非常强大,其语法类似于面向对象的查询语言,可以实现类似关系数据库单表查询的绝大部分功能。

Python 程序要访问 MongoDB,需要使用第三方模块 pymongo。

2. 安装 pymongo

pymongo 是 python 访问 mysql 数据库的模块。首先检查是否已经安装了 pymongo 模块,在 python 交互模式下 import pymongo,如下所示:

>>> import pymongo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'pymongo'

如果出现错误:ModuleNotFoundError,则表示还没有安装 pymongo,使用 pip3 install mysql 安装 pymongo,如下所示:

$ pip3 install pymongo
Collecting pymongo
...
Installing collected packages: pymongo
Successfully installed pymongo-3.10.1

3. 启动 MongoDB

在 MonoDB 中创建数据库 school,在后面的小节中,将对数据库 school 进行增删改查。输入如下命令启动 MongoDB:

$ mkdir school
$ mongod --dbpath=./school >/dev/null
  • 在第 1 行,创建目录 school,用于存放 MongoDB 数据库 school 的内容
  • 在第 2 行,启动 MongoDB 的服务,指定 dbpath 为目录 school

4. 连接数据库

pymongo.MongoClient 方法连接 MongoDB,返回一个 MongoCLient 对象,示例如下:

import pymongo

def open_db():
    global mongo
    global school
    global students

    mongo = pymongo.MongoClient('mongodb://localhost')
    school = mongo['school']
    students = school['students']    
  • 在第 1 行,引入 pymongo 模块
  • 在第 3 行,定义方法 open_db() 连接 MongoDB,后面的例子会引用该方法
  • 在第 4 行到第 6 行,声明 3 个全局变量
    • mongo 是连接 MongoDB 的对象
    • school 是 MongoDB 中的数据库
    • students 是 MongoDB 中的表
  • 在第 8 行,使用 ‘mongodb://localhost’ 作为 url 连接本地的 MongoDB
  • 在第 9 行,在 MongoDB 中创建数据库 school
  • 在第 10 行,在数据库 school 中创建表 students

5. 列出数据

MongoDB 的表提供了 find() 方法,查询表中的所有数据,类似 SQL 中的 SELECT * 操作:

def list_students():
    for student in students.find():
        print(student)
  • 在第 1 行,定义方法 list_students() 列出所有的学生的信息,后面的例子会引用该方法
  • 在第 2 行,students.find() 查询表 students 中所有的数据

6. 增加数据

6.1 增加一条数据

MongoDB 的表提供了 insert() 方法,向表中插入一条数据:

def add_one_student(sno, name, age):
    student = {'sno': sno, 'name': name, 'age': age}
    students.insert_one(student)
  • 在第 1 行,函数 add_one_student 向表 students 增加一个学生
  • 在第 2 行,构造一个字典对象 student
  • 在第 3 行,将字典 student 插入到表 students 中

编写测试程序如下:

add_one_student('1', 'tom', 11)
add_one_student('2', 'jerry', 12)
list_students()

程序运行输出如下:

{'_id': ObjectId('5ee328013ee9af43360b7a65'), 'sno': '1', 'name': 'tom', 'age': 11}
{'_id': ObjectId('5ee328013ee9af43360b7a66'), 'sno': '2', 'name': 'jerry', 'age': 12}

6.2 增加多条数据

MongoDB 的表提供了 insert_many() 方法,向表中插入多条数据:

def add_many_students():
    tom = {'sno': '1', 'name': 'tom', 'age': 11}
    jerry = {'sno': '2', 'name': 'jerry', 'age': 12}
    array = [tom, jerry]
    students.insert_many(array)
  • 在第 1 行,函数 add_many_students 向表 students 增加多个学生
  • 在第 2 行,构造一个字典对象 tom
  • 在第 3 行,构造一个字典对象 jerry
  • 在第 5 行,将学生 tom 和学生 jerry 插入到表 students 中

编写测试程序如下:

add_many_students()
list_students()

程序运行输出如下:

{'_id': ObjectId('5ee3281b673bfa2333f3c1f1'), 'sno': '1', 'name': 'tom', 'age': 11}
{'_id': ObjectId('5ee3281b673bfa2333f3c1f2'), 'sno': '2', 'name': 'jerry', 'age': 12}

6.3 用于测试的数据

编写函数 add_students_for_test,向表 students 中插入 4 条数据用于测试,在后面的小节将引用这个函数。

def add_students_for_test():
    add_one_student('1', '张三', 11)
    add_one_student('2', '李四', 12)
    add_one_student('3', '王五', 13)
    add_one_student('4', '李四', 14)

7. 修改数据

7.1 修改一条数据

MongoDB 的表提供了 update_one() 方法,修改表中符合查询条件的第一条数据:

def update_one_student(sno, name):
    condition = {'sno': sno}
    value = {'$set': {'name': name}}
    students.update_one(condition, value)
  • 在第 2 行,设置查询条件为学号 sno
  • 在第 3 行,修改查询结果的姓名 name
  • 在第 4 行,查询表 students 中学号为 sno 的学生,修改符合查询条件的第一个学生的姓名 name

编写测试程序如下:

add_students_for_test()
update_one_student('1', 'ZhangSan')
update_one_student('2', 'LiSi')
list_students() 
  • 在第 2 行,查找学号为 ‘1’ 的学生,将其姓名 name 修改为 ‘ZhangSan’
  • 在第 3 行,查找学号为 ‘2’ 的学生,将其姓名 name 修改为 ‘LiSi’

程序运行输出如下:

{'_id': ObjectId('5ee3284f14c80d192f214ea0'), 'sno': '1', 'name': 'ZhangSan', 'age': 11}
{'_id': ObjectId('5ee3284f14c80d192f214ea1'), 'sno': '2', 'name': 'LiSi', 'age': 12}
{'_id': ObjectId('5ee3284f14c80d192f214ea2'), 'sno': '3', 'name': '王五', 'age': 13}
{'_id': ObjectId('5ee3284f14c80d192f214ea3'), 'sno': '4', 'name': '李四', 'age': 14}

7.2 修改多条数据

MongoDB 的表提供了 update_many() 方法,修改表中符合查询条件的所有数据:

def update_many_students(old_name, new_name):
    condition = {'name': old_name}
    value = {'$set': {'name': new_name}}
    students.update_many(condition, value)
  • 在第 2 行,设置查询条件为姓名 name
  • 在第 3 行,修改查询结果的姓名 name
  • 在第 4 行,查询表 students 中姓名为 name 的学生,修改所有符合查询条件学生的姓名 name

编写测试程序如下:

add_students_for_test()
update_many_students('李四', 'LiSi')
list_students()
  • 在第 2 行,查找姓名为 ‘李四’ 的学生,将其姓名 name 修改为 ‘LiSi’

程序运行输出如下:

{'_id': ObjectId('5ee328758ab7b33517380c8f'), 'sno': '1', 'name': '张三', 'age': 11}
{'_id': ObjectId('5ee328758ab7b33517380c90'), 'sno': '2', 'name': 'LiSi', 'age': 12}
{'_id': ObjectId('5ee328758ab7b33517380c91'), 'sno': '3', 'name': '王五', 'age': 13}
{'_id': ObjectId('5ee328758ab7b33517380c92'), 'sno': '4', 'name': 'LiSi', 'age': 14}

8. 删除数据

8.1 删除一条数据

MongoDB 的表提供了 delete_one() 方法,删除表中符合查询条件的第一条数据:

def delete_one_student(sno):
    student = {'sno': sno}
    students.delete_one(student)
  • 在第 2 行,设置查询条件为学号 sno
  • 在第 3 行,查询表 students 中学号为 sno 的学生,删除符合查询条件的第一个学生

编写测试程序如下:

add_students_for_test()
delete_one_student('1')
delete_one_student('2')
list_students()
  • 在第 2 行,删除学号为 ‘1’ 的学生
  • 在第 3 行,删除学号为 ‘2’ 的学生

程序运行输出如下:

{'_id': ObjectId('5ee328a441b99d0ffd2127ab'), 'sno': '3', 'name': '王五', 'age': 13}
{'_id': ObjectId('5ee328a441b99d0ffd2127ac'), 'sno': '4', 'name': '李四', 'age': 14}

8.2 删除多条数据

MongoDB 的表提供了 delete_many() 方法,删除表中所有符合查询条件的数据:

def delete_many_students(name):
    student = {'name': name}
    students.delete_many(student)
  • 在第 2 行,设置查询条件为姓名 name
  • 在第 3 行,查询表 students 中姓名为 name 的学生,删除所有符合查询条件的学生

编写测试程序如下:

add_students_for_test()
delete_many_students('李四')
list_students()

程序运行输出如下:

{'_id': ObjectId('5ee328d182f2558674a683db'), 'sno': '1', 'name': '张三', 'age': 11}
{'_id': ObjectId('5ee328d182f2558674a683dd'), 'sno': '3', 'name': '王五', 'age': 13}

8.3 删除所有数据

如果如果传递给 delete_many() 一个空的查询对象,则删除表中所有的数据:

def delete_all_students():
    student = {}
    students.delete_many(student)

编写测试程序如下:

add_students_for_test()
delete_all_students()
list_students()

将数据全部删除了,程序输出为空。