第十四章 数据存储

 
如果要保存非常多的数据,而且要求快速被程序识别,甚至在海量数据中搜索到想要的数据,就要使用结构化的存储方式,而且要配有相应的处理引擎。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有多种选择,都是通过模块支持的。比较著名的有SQLAIchemySQLObject

  • 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())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值