如果要保存非常多的数据,而且要求快速被程序识别,甚至在海量数据中搜索到想要的数据,就要使用结构化的存储方式,而且要配有相应的处理引擎。Python通过模块支持了大量的数据存储和查找解决方案,如基于纯文本的JSON、XML、关系型数据库 MySQI、还有NoSQL、Excel等。
14.1 处理 XML 格式的数据
14.1.1 读取与搜索 XML 文件
XML文件已经被广泛使用在各种应用中。尽管目前很多应用都不会将大量的数据保存在XML文件中,但至少会使用XML文件保存一些配置信息。在Python语言中需要导入XML模块或其子模块,并利用其中提供的API来操作XML文件。例如,要读取XML文件需要导入xml.etree.ElementTree模块,并通过该模块的parse函数读取XML文件。
products.xml 待处理文本
<!-- products.xml -->
<root>
<products>
<product uuid= '1234'>
<id>10000</id>
<name>iPhone9</name>
<price>9999</price>
</product>
<product uuid='4321'>
<id>20000</id>
<name>特斯拉</name>
<price>800000</price>
</product>
<product uuid='5678'>
<id>30000</id>
<name>Mac Pro</name>
<price>40000</price>
</product>
</products>
</root>
用下边的脚本处理上边的文本
from xml.etree.ElementTree import parse
# 开始分析products.xml文件
doc = parse('./products.xml')
#通过xPath搜索子节点集合,然后对这个子节点集合进行迭代
for item in doc.iterfind('products/product'):
# 读取product节点的id子节点的值
id = item.findtext('id')
# 读取product节点的name子节点的值
name = item.findtext('name')
# 读取product节点的price子节点的值
price = item.findtext('price')
# 读取product节点的uuid属性的值
print('uuid','=',item.get('uuid'))
print('id','=',id)
print('name', '=',name)
print('price','=',price)
print('-------------')
输出结果如下:
从前面的代码可知,读取一个节点的子节点的值要使用findnext方法,读取节点属性的值,直接在当前节点下使用get方法即可。XML文件要有一个根节点,本例是<root>,不能直接用<products>作为顶层节点,因为要对该节点进行迭代。
14.1.2 字典转换为 XML 字符串
生成XML文件的方式很多,可以按字符串方式生成XML文件,也可以按其他方式生成文件。将字典转换为XML文件需要使用dicttoxml模块中的dicttoxml函数,在导入 dicttoxml模块之前需要先使用下面的命令安装dicttoxml模块。
pip install dicttoxml
要注意的是,如果本机安装了多个版本的 Python,一定要确认调用的pip命令是否为当前正在使用的Python版本中的pip,如果调用错了,则会将dicttoxml模块安装到其他 Python版本中,而当前正在使用的Python 版本还是无法导入dicttoxml模块。
如果要想解析XML字符串,可以导入xmI.dom.minidom模块,并使用该模块中的parseString 函数。
import dicttoxml
import os
from xml.dom.minidom import parseString
# 定义一个字典
d = [20,'names',
{'name':'Bill','age':30,'salary':2000},
{'name':'王军','age':34,'salary':3000},
{'name':'John','age':25,'salary':2500}]
# 将字典转换为XML格式(bytes形式)
bxml = dicttoxml.dicttoxml(d, custom_root = 'persons')
# 将bytes形式的XML数据按utf-8编码格式解码成XML字符串
xml = bxml.decode('utf-8')
print(xml)
# 解析XML字符串
dom = parseString(xml)
# 生成带缩进格式的字符串
prettyxml = dom.toprettyxml(indent = ' ')
# 以只写和utf-8编码格式的方式打开persons.xml文件
os.makedirs('ufo', exist_ok = True)
f = open('ufo/persons.xml', 'w',encoding='utf-8')
# 将带格式的XML文件写入persons.xml文件
f.write(prettyxml)
f.close()
输出结果如下:
<?xml version="1.0" ?>
<persons>
<item type="int">20</item>
<item type="str">names</item>
<item type="dict">
<name type="str">Bill</name>
<age type="int">30</age>
<salary type="int">2000</salary>
</item>
<item type="dict">
<name type="str">王军</name>
<age type="int">34</age>
<salary type="int">3000</salary>
</item>
<item type="dict">
<name type="str">John</name>
<age type="int">25</age>
<salary type="int">2500</salary>
</item>
</persons>
14.1.3 XML 字符串转换为字典
import xmltodict
# 打开文件并读取所有内容,注意需要安装xmltodict模块
f = open('ufo/persons.xml','rt',encoding="utf-8")
xml = f.read()
import pprint
# 分析XML字符串,并转化为字典
d = xmltodict.parse(xml)
# 输出字典内容,一大串显示
print(d)
# 格式化后,输出字典
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(d)
f.close()
14.2 处理 JSON 格式的数据
JSON格式要比XML格式更轻量,所以现在很多数据都选择使用JSON格式保存,尤其是需要通过网络传输数据时,这对于移动应用更有优势,因为保存同样的数据,使用JSON格式要比使用XML格式的数据尺寸更小,所以传输速度更快,也更节省流量。
JSON格式的数据可以保存数组和对象,JSON数组用一对中括号将数据括起来,JSON对象用一对大括号将数据括起来。注意,key和字符串类型的值要用双引号括起来,不能使用单引号。
[
{"item1" : "value1", "item2" : 30,"item3" : 10},
{"item1" : "value2", "item2" : 30,"item3" : 20}
]
14.2.1 JSON 字符串与字典互相转换
-
将字典转换为JSON字符串需要使用json模块的dumps函数,该函数需要将字典通过参数传然后返回与字典对应的JSON字符串。
-
使用json模块的 loads函数,该函数通过参数传入JSON字符串,然后返回与该JSON字符串对应的字典。
-
使用 eval函数将JSON格式字符串当作普通的 Python 代码执行,eval函数会直接返回与JSON格式字符串对应的字典。
# 将JSON字符串转换为字典
data = eval(s)
print(type(data))
print(data)
# 输出字典key为company的值
print(data['company'])
# 打开文件,读取所有内容
f = open('./products.json','r',encoding='utf-8')
jsonStr = f.read()
# 将JSON字符串转换为字典
json1 = eval(jsonStr)
# 将JSON字符串转换为字典
json2 = json.loads(jsonStr)
# 输出指定内容
print(json1)
print(json2)
print(json2[0]['name'])
f.close()
尽管eval函数与loads 函数都可以将JSON字符串转换为字典,但建议使用loads函数进行转换,因为eval 函数可以执行任何Python 代码,如果JSON字符串中包含了有害的Python 代码,执行JSO字符串可能会带来风险。
14.2.2 将 JSON 字符串转换为类实例
loads函数不仅可以将JSON字符串转换为字典,还可以将JSON字符串转换为类实例。转换原理是通过loads函数的object_hook 关键字参数指定一个类或一个回调函数。具体处理方式如下:
- 指定类 : loads函数会自动创建指定类的实例,并将由JSON字符串转换成的字典通过类的构造方法传入类实例,也就是说,指定的类必须有一个可以接收字典的构造方法。
- 指定回调函数 : loads函数会调用回调函数返回类实例,并将由JSON字符串转换成的字典传入回调函数,也就是说,回调函数也必须有一个参数可以接收字典。
loads函数将JSON字符串转换为类实例的本质是先将JSON字符串转换为字典,然后再将字典转换为对象。区别是指定类时,创建类实例的任务由 loads 函数完成,而指定回调函数时,创建类实例的任务需要在回调函数中完成。
import json
# 定义Product类,d是要传入的字典
class Product:
def __init__(self, d):
self.__dict__ = d
# 打开文件并读取所有内容
f = open('./product.json','r')
jsonStr = f.read()
# 通过指定类的方式,将JSON字符串转换为Product对象,并输出对象属性
my1 = json.loads(jsonStr, object_hook=Product)
print('name', '=', my1.name)
print('price', '=', my1.price)
print('count', '=', my1.count)
print('-----------')
# 定义一个将字典转换为Product对象的函数
def json2Product(d):
return Product(d)
# 通过指定回调函数的方式,将JSON字符串转换为Product对象,并输出对象属性
my2 = json.loads(jsonStr, object_hook=json2Product)
print('name', '=', my2.name)
print('price', '=', my2.price)
print('count', '=', my2.count)
f.close()
14.2.3 将类实例转换为 JSON 字符串
dumps函数不仅可以将字典转换为JSON字符串,还可以将类实例转换为JSON字符串。dumps函数需要通过default关键字参数指定一个回调函数,在转换的过程中,dumps函数会向这个回调函数传入类实例(通过dumps 函数第1个参数传入),而回调函数的任务是将传入的对象转换为字典,然后dumps函数再将由回调函数返回的字典转换为JSON字符串。
import json
class Product:
# 通过类的构造方法初始化3个属性
def __init__(self, name,price,count):
self.name = name
self.price = price
self.count = count
# 定义将Product对象转换为字典的函数
def product2Dict(obj):
return {
'name': obj.name,
'price': obj.price,
'count': obj.count
}
# 创建Product类的实例
product = Product('特斯拉',1000000,20)
# 将Product类的实例转换为JSON字符串,其中调用了product2Dict回调函数
# 设置ensure_ascii=False返回的JSON正常显示中文
jsonStr = json.dumps(product, default=product2Dict,ensure_ascii=False)
print(jsonStr)
14.2.4 类实例列表与JSON字符串互相转换
如果JSON字符串是一个类实例数组或一个类实例的列表,也可以互相转换。
import json
class Product:
def __init__(self, d):
self.__dict__ = d
f = open('./products.json','r', encoding='utf-8')
jsonStr = f.read()
# 将JSON字符串转换为Product对象列表(products)
products = json.loads(jsonStr, object_hook=Product)
for product in products:
print('name', '=', product.name)
print('price', '=', product.price)
print('count', '=', product.count)
f.close()
# 将Product对象转换为字典的函数
def product2Dict(product):
return {
'name': product.name,
'price': product.price,
'count': product.count
}
# 将Product对象列表(products)转换为JSON对象
jsonStr = json.dumps(products, default=product2Dict,ensure_ascii=False)
print(jsonStr)
14.3 将 JSON 字符串转换为 XML 字符串
将JSON字符串转换为XML字符串其实只需要做一下中转即可,也就是先将JSON字符串转换为字典,然后再使用dicttoxml模块中的dicttoxml函数将字典转换为XML字符串。
import json
import dicttoxml
f = open('./products.json','r',encoding='utf-8')
jsonStr = f.read()
# 将json字符串转换为字典
d = json.loads(jsonStr)
print(d)
# 将字典转换为XML字符串
xmlStr = dicttoxml.dicttoxml(d).decode('utf-8')
print(xmlStr)
f.close()
14.4 MySQL 数据库(重点)
MySQL是非常常用的关系型数据库。在Python语言中需要使用pymysql模块来操作MySQL 数据库。
如果使用的是 Anaconda 的 Python环境,则需要使用下面的命令安装pymysql模块:
conda install pymysql
如果使用的是标准的Python环境,需要使用pip命令安装pymysql模块:
pip install pymysql
- connect函数 : 连接数据库,根据连接的数据库类型不同,该函数的参数也不同。connect 函数返回Connection对象。
- execute方法 : 用于执行SQL语句,该方法属于Cursor对象。
- commit方法 : 在修改数据库后,需要调用该方法提交对数据库的修改,commit方法属于Cursor对象。
- rollback方法 : 如果修改数据库失败,一般需要调用该方法进行数据库回滚,也就是将数据库恢复成修改之前的样子。
from pymysql import *
import json
# 连接数据库
def connectDB():
db=connect("127.0.0.1","root","12345678","meituan",charset='utf8')
return db
db = connectDB()
print(type(db))
# 创建表
def createTable(db):
# 获取cursor对象
cursor=db.cursor()
sql='''CREATE TABLE persons
(id INT PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
age INT NOT NULL,
address CHAR(50),
salary REAL);'''
try:
cursor.execute(sql)
# 提交到数据库执行
db.commit()
# 提交成功直接跳出函数了
return True
except:
# 如果发生错误则回滚
db.rollback()
# 有回滚时会走到这一步
return False
# 增删操作
def insertRecords(db):
cursor=db.cursor()
try:
cursor.execute('DELETE FROM persons')
cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (1, 'Paul', 32, 'California', 20000.00 )");
cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (2, 'Allen', 25, 'Texas', 15000.00 )");
cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (3, 'Teddy', 23, 'Norway', 20000.00 )");
cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 )");
# 提交到数据库执行
db.commit()
return True
except Exception as e:
print(e)
# 如果发生错误则回滚
db.rollback()
return False
# 查询操作
def selectRecords(db):
cursor=db.cursor()
sql='SELECT name,age,salary FROM persons ORDER BY age DESC'
# 仅执行,返回的是None,需要调用fetchall方法获取结果
cursor.execute(sql)
# 获取全部查询结果
results=cursor.fetchall()
# 输出查询结果
print(results)
# 字段名
fields = ['name','age','salary']
# 记录值
records=[]
# 将查询结果重新组织成字典形式
for row in results:
records.append(dict(zip(fields,row)))
return json.dumps(records)
# 判断创建表是否成功
if createTable(db):
print('成功创建persons表')
else:
print('persons表已经存在')
# 判断插入记录是否成功
if insertRecords(db):
print('成功插入记录')
else:
print('插入记录失败')
# 以字典的形式输出查询结果
print(selectRecords(db))
db.close()
14.5 ORM(重点)
如果直接在程序中嵌入SQL语句,会增加程序对数据库的耦合度,要是更换数库,可能还需要修改程序中的SQL语句。为了解决这个问题,出现了ORM(Object Relational Mapping 对象关系映射)技术,可以将纯SQL抽象化,或者说将SQL语句直接映射成Python对象,程序员需要使用Python对象,就可以操作各种类型的数据库,ORM 系统会根据不同类型的数据库,以及应的操作,自动生成SQL语句(优化困难)。因此,使用ORM编写的应用在更换数据库时,不需要修改程序源代码。
绝大多数编程语言都支持ORM,有的是直接内置的,有的是通过第三方实现的。在 Python 语言中使用ORM有多种选择,都是通过模块支持的。比较著名的有SQLAIchemy和SQLObject 。
- SQLAlchemy中对象的抽象化非常完美,可以更灵活地提交原生的SQL语句。
- SQLObject更加简单,更加类似 Python,更快速。
14.5.1 SQLAIchemy
如果使用的是Anaconda Python开发环境,那么SQLAlchemy已经集成到Anaconda中,无须进行安装。如果非要再安装一遍SQLAlchemy,可以使用下面的命令 :
conda install -c anaconda sqlalchemy
如果使用的是官方的Python开发环境,需要使用下面的命令安装SQLAlchemy :
pip install SQLAlchemy
在使用SQLAlchemy操作数据库时需要首先导入sqlalchemy模块和 sqlalchemy.ext.declarative模块。
1. 连接数据库
sqlalchemy模块中的create_engine函数负责指定连接数据库需要的信息,如果连接的是 MySQL这样的网络关系型数据库,需要数据库所在的服务器IP(或域名)、端口号、数据库名称、用户名、密码、编码等信息。create_engine函数会返回一个sqlalchemy.engine.base.Engine对象,然后使用该对象的connect方法连接数据库。
from sqlalchemy import create_engine,MetaData,Table,Column,Integer,String,Float,exc, orm
from sqlalchemy.ext.declarative import declarative_base
# 定义MysoL连接字符串
mysql = 'mysql+pymysql://root:12345678@localhost:3306/geekori?charset=utf8'
# 创建数据库引擎(返回sqlalchemy.engine.base.Engine对象)
engine = create_engine(mysql,encoding='utf-8')
# 开始连接数据库,调用对象的connect方法连接数据库
# 连接后返回engine对象
engine.connect()
2. 创建表
由于创建表需要指定表的元数据,也就是字段名、字段数据类型等信息,所以首先要创建MetaData对象,该对象通过构造方法的参数与engine关联,然后再创建一个Table对象用于指定表中字段的相关信息,Table对象需要与MetaData对象关联,最后调用MetaData对象的create_all方法创建表。
from sqlalchemy import create_engine,MetaData,Table,Column, Integer,String,Float,exc,orm
# 创建MetaData对象
metadata = MetaData(engine)
# 创建用于描述表中字段信息的Table对象
person = Table('users', metadata,
column('id', Integer, primary_key = True) ,
Column('name ', string (30)) ,
Column('age', Integer))
# 创建表
metadata.create_all(engine)
3. 创建会话
对数据库的任何操作都需要先创建 Session对象。
from sqlalchemy import create_engine,MetaData,Table,Column, Integer,String,Float,exc,orm
session = orm.sessionmaker(bind=engine)
session = session()
4. 定义与表对应的 Python 类
ORM的重要特性就是用Python类与数据库中的表对应,所以对数据表的增、删、改、查操作,都离不开与表对应的 Python类。因此,在对数据表进行增、删、改、查操作之前,要先建立一个Python类,而且这个 Python类需要从declarative_base函数返回的Base类继承。
from sqlalchemy import create_engine,MetaData,Table,Column,Integer,string,Float,exc, orm
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
# 与users表对应的User类
class User(Base) :
# 指定表名
_tablename__= 'users'
id = Column(Integer, primary_key=True)
name = Column(String(30))
age = Column (Integer)
5. 插入记录
向表中添加记录就是创建 Python类实例的过程,对于本例,需要创建User对象。然后通过add方法将User对象添加进Session。注意,对数据库的任何修改操作,都需要调用会话的commit方法提交,否则修改不会生效。
user = User(id=1,name='John',age=50)
session.add(user)
#必须调用commit方法,对数据库的修改才会生效
session.commit()
6. 删除记录
从表中删除记录需要调用Session对象的delete方法,该方法需要传入一个与表对应的Python的实例。所以在删除记录之前,要么先从数据库中查询出要删除的对象,要么使用自己创建的对象如本例中的user。
user = User(id=1,name='John',age=50)
session.add(user)
# 必须调用commit方法,对数据库的修改才会生效
session.commit()
# 删除前面插入的记录
session.delete(user)
# 必须调用commit方法,对数据库的修改才能生效
session.commit()
7. 更新记录
与删除记录类似,更新记录也需要与记录对应的对象,直接修改对象中的属性,然后调用commit方法提交即可。
user = User(id=1,name='John',age=50)
session.add (user)
#必须调用commit方法,对数据库的修改才会生效
session.commit()
#将name字典值修改为Mike
user.name = 'Mike'
#必须调用commit方法,对数据库的修改才能生效
session.commit()
8. 查询记录
使用Session对象的query方法可以查询记录,还可以通过filter方法指定查询条件,query方法或filter方法以sqlalchemy.orm.query.Query对象形式返回查询结果,这是一个可迭代的对象,所以需要对查询结果进行迭代,才能得到所有的查询结果。
query = session.query(Person).filter(User.name == 'John')
9. 关闭会话
操作数据库的最后一步是调用Session的close方法关闭会话。
一个完整示例:调用sqlalchemy模块的API对数据表进行增、删、改、查 。
from sqlalchemy import create_engine,MetaData,Table,Column,Integer,String,Float,exc,orm
from sqlalchemy.ext.declarative import declarative_base
import uuid
# 定义mysql连接串
mysql = 'mysql+pymysql://root:12345678@localhost:3306/meituan?charset=utf8'
# 定义要操作的表名
tableName = 'persons1'
engine = create_engine(mysql,encoding='utf-8')
metadata = MetaData(engine)
person = Table(tableName, metadata,
Column('id', Integer, primary_key = True),
Column('name', String(30)),
Column('age', Integer),
Column('address', String(100)),
Column('salary', Float))
# 连接mysql
engine.connect()
# 初始化创表
metadata.create_all(engine)
# 创建与表对应的类
Base = declarative_base()
class Person(Base):
__tablename__= tableName
id = Column(Integer,primary_key=True)
name = Column(String(30))
age = Column(Integer)
address = Column(String(100))
salary= Column(Float)
# 建立会话
Session = orm.sessionmaker(bind=engine)
session = Session()
# 删除表记录
session.query(Person).delete()
session.commit()
# 插入记录
person1 = Person(id=10,name='Bill',age=30,address='地球',salary=1234)
person2 = Person(id=20,name='Mike',age=40,address='火星',salary=4321)
person3 = Person(id=30,name='John',age=50,address='氪星',salary=10000)
session.add(person1)
session.add(person2)
session.add(person3)
# 提交即保存到数据库:
session.commit()
print('成功插入记录')
# 先查询后更新
session.query(Person).filter(Person.name == 'Mike').update({'address': '千星之城'})
query = session.query(Person).filter(Person.name == 'John')
print(query)
# 将查询结果转化为单一对象,此处必须保证查询结果只有一条记录
person = query.scalar()
# 修改对象属性值
person.age = 12
person.salary=5432
session.commit()
print('成功更新了记录')
# 利用组合条件查询,循环迭代查询输出
persons = session.query(Person).filter((Person.age >= 10) & (Person.salary >= 2000))
for person in persons:
print('name','=',person.name,end=' ')
print('age','=',person.age, end = ' ')
print('salary','=',person.salary)
# 查询的第1条记录的name字段值
print(persons.first().name)
# 输出查询结果中的第2条记录的name字段值
print(persons.offset(1).scalar().name)
# 关闭session:
session.close()
14.5.2 SQLObject
使用SQLObject操作数据库首先要使用下面的命令安装sqlobject模块,如果在机器上安装了多个Python版本,请确认使用的pip命令是当前正在使用的 Python 版本中的pip命令。
pip install sqlobject
SQLObject对数据库的操作要比SQLAlchemy简单得多。首先需要使用connectionForURL函数连接数据库,然后要定义一个 Python类来描述数据库中的一个表,可以将这个Python类称为ORM类,由该类创建的对象称为ORM对象。ORM类需要从SQLObject类继承,在该类中要定义属性(对应数据表中的字段)的类型和其他信息。
创建完ORM 类,可以进行数据库的各种操作,如使用dropTable方法删除表、使用createTable方法创建表。创建一个ORM类的实例,会自动将相应的记录插入到表中,不需要像SQLAlchemy样再调用commit方法提交。删除和修改记录也类似,对ORM对象的任何修改都会立刻体现在数据表中。查询数据要使用selectBy 方法,该方法可以指定查询条件,通过返回ORM对象列表的方式返回查询结果集。
from sqlobject import *
from sqlobject.mysql import builder
import json
# 定义mysql连接串
mysql = 'mysql://root:12345678@localhost:3306/meituan?charset=utf8'
# 连接数据库
sqlhub.processConnection = connectionForURI(mysql,driver='pymysql')
# 定义ORM类,需要从SQLObject继承
class Person(SQLObject):
class sqlmeta:
table='t_persons'
name = StringCol(length=30)
age = IntCol()
address = StringCol(length=30)
salary = FloatCol()
# 删除表
try:
Person.dropTable()
except:
pass
# 创建表
Person.createTable()
print('成功创建了Persons表')
# 插入数据
person1 = Person(name='Bill', age=55,address='地球',salary=1234)
person2 = Person(name='Mike', age=65,address='月球',salary=4321)
person3 = Person(name='John', age=15,address='火星',salary=4000)
print('成功插入了3条记录')
# 修改表数据
person2.name = "李宁"
person2.address= "赛博坦"
# 查询表数据
persons = Person.selectBy(name='Bill')
print(persons[0])
print(persons[0].id)
print(persons[0].name)
print(persons[0].address)
# 将person对象转换为字典
def person2Dict(obj):
return {
'id': obj.id,
'name': obj.name,
'age': obj.age,
'address':obj.address,
'salary':obj.salary
}
# 将person对象转换为json字符串
jsonStr = json.dumps(persons[0], default=person2Dict,ensure_ascii=False)
print(jsonStr)
# 删除表数据
persons[0].destroySelf()
14.6 非关系型数据库
14.6.1 NoSQL 简介(略)
14.6.2 MongoDB 数据库
MongoDB是非常著名的文档数据库,所有的数据以文档形式存储(通常关联表很多时性能较差,可以考虑非关系型数据库,相关数据存放一个文档中,这样查询性能会更好),常见博客加相关评论的查询等等。
14.6.3 pymongo 模块(了解)
在 Python语言中使用MongoDB 数据库需要先导入pymongo模块,如果使用了Anaconda Python开发环境,pymongo模块已经被集成到Anaconda,如果使用的是标准的 Python开发环境,需要使用下面的命令安装pymongo模块 :
pip install pymongo
操作MongoDB数据库与操作关系型数据库需要完成的工作类似,如连接数据库、创建表、查询数据等。只不过在MongoDB数据库中没有数据库和表的概念,一切都是文档。在Python 语言中,文档主要是指列表和字典。也就是说,MongoDB数据库中存储的都是列表和字典数据。连接MongoDB数据库需要创建MongoClient类的实例,连接MongoDB 数据库后,就可以按文档的方式操作数据库。
from pymongo import *
# 连接数据库(连接串等局部连接过程略)
Client = MongoClient()
# 打开或创建名为data的collection,collection相当于关系型数据库中的数据库
# 在mongodb数据库中,collection是文档的集合
db = Client.data
# db = Client['data'] ,使用类似引用字典值的方式打开或创建collection
# collection = db['test_collection']
# 定义要插入的文档(字典)
person1 = {"name": "Bill", "age": 55, "address": "地球", "salary": 1234.0}
person2 = {"name": "Mike", "age": 12, "address": "火星", "salary": 434.0}
person3 = {"name": "John", "age": 43, "address": "月球", "salary": 6543.0}
# 创建或打开一个名为persons的文档,persons相当于关系型数据库中的表
persons = db.persons
# 删除persons文档中的所有数据
persons.delete_many({'age':{'$gt':0}})
# 使用insert_one方法插入文档
personId1 = persons.insert_one(person1).inserted_id
personId2 = persons.insert_one(person2).inserted_id
personId3 = persons.insert_one(person3).inserted_id
print(personId3)
# 也可以使用insert_many方法一次插入多个文档
# personList = [person1,person2,person3]
# result = persons.insert_many(personList)
# print(result.inserted_ids)
# 搜索persons文档中的第一条子文档,相当于关系型数据库中的记录
print(persons.find_one())
print(persons.find_one()['name'])
# 搜索所有数据
for person in persons.find():
print(person)
print('--------------')
# 更新第1个满足条件的文档中的数据
persons.update_one({'age':{'$lt':50}},{'$set':{'name':'超人'}})
# update_many更新所有满足条件的文档
# 只删除满足条件的第1个文档
# persons.delete_one({'age':{'$gt':0}})
# 搜索指定数据,所有age小于50的文档
for person in persons.find({'age':{'$lt':50}}):
print(person)
print('--------------')
# 搜索指定数据,所有age大于50的文档
for person in persons.find({'age':{'$gt':50}}):
print(person)
# 输出persons文档中的总数(总记录数)
print('总数', '=', persons.count())