热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

唤醒手腕Python全栈工程师学习笔记(持久存储篇)

这个篇目是“持久存储篇”,讲的就是Python操作数据库,这边介绍3种数据库,分别是MySQL、Redis、Mongodb1.Pytho

这个篇目是“持久存储篇”,讲的就是Python操作数据库,这边介绍3种数据库,分别是MySQL、Redis、Mongodb


1. Python操作MySQL数据库

MySQL属于传统的关系型数据库产品,其开放式的架构使得用户的选择性很强,而且随着技术的逐渐成熟,MySQL支持的功能也越来越多,性能也在不断地提高,对平台的支持也在增多,此外,社区的开发与维护人数也很多。

当下,MySQL因为其功能稳定、性能卓越,且在遵守GPL协议的前提下,可以免费使用与修改,因此深受用户喜爱。

自甲骨文公司收购MySQL之后,MySQL在商业数据库与开源数据库领域的市场占有份额都跃居第一,这样的格局引起了部分业内人士的担忧,因为商业数据库的老大有可能将MySQL闭源,为了避免Oracle将MySQL闭源,而无开源的类MySQL数据库可用,MySQL社区采用了分支的方式,MariaDB数据库就这样诞生了。

MariaDB是一个向后兼容的数据库产品,可能会在以后替代MySQL,其官方地址为https://mariadb.org/。不过,这里还是建议大家选择更稳定且使用更广泛的MySQL数据库,可以先测试MariaDB数据库,等使用的人员多一些,社区更活跃后再正式考虑使用也不迟。


1.1 下载pymysql第三方库

python连接Mysql数据库,借助的第三方库是pymysql,进行下载pymysql:

pip install pymysql -i 镜像源地址

pip的仓库一般都是在国外的服务器上,加了镜像源可以提供下载的速度。

常见pip镜像源(国内源)

清华:https://pypi.tuna.tsinghua.edu.cn/simple

阿里云:http://mirrors.aliyun.com/pypi/simple/

中国科技大学: https://pypi.mirrors.ustc.edu.cn/simple/

华中理工大学:http://pypi.hustunique.com/

山东理工大学:http://pypi.sdutlinux.org/

豆瓣:http://pypi.douban.com/simple/


临时使用pip镜像源可以在使用pip的时候加参数:-i https://pypi.tuna.tsinghua.edu.cn/simple


Linux下,修改 ~/.pip/pip.conf (没有就创建一个文件夹及文件。文件夹要加“.”,表示是隐藏文件夹)

[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host=mirrors.aliyun.com

1.2 连接MySQL数据库

在项目中,导入pymysql第三方库,配置连接mysql数据库:

import pymysqlconn = pymysql.connect(host='127.0.0.1', # 连接名称,默认127.0.0.1user='root', # 用户名passwd='root', # 密码port=3306, # 端口,默认为3306db='pythondb', # 数据库名称charset='utf8', # 字符编码
)print(conn)

连接成功会打印连接对象:


pymysql.connect(···)返回就是Connection类的对象,接下来,看下Connection类的源码:
在这里插入图片描述


1.3 ini文件读取数据库配置项

配置参数,就是Connect类生成对象需要的参数,当然这些参数一般我们会建立配置文件来进行配置,配置文件可以是.conf,也可以是.ini,就是把配置项从程序代码中解耦出来:

这边举例,建立mysql_db.ini文件,作为连接MySQL的配置文件:


配置文件的配置项,读取的时候默认都是以字符串类型的,对应字符串,不需要加双引号""


[mysql]
host=127.0.0.1
;连接名称,默认127.0.0.1
user=root
;用户名
passwd=root
;密码
port=3306
;端口,默认为3306
db=pythondb
;数据库名称
charset=utf8
;字符编码

建立完配置文件mysql_db.ini,就需要在项目中导入配置文件中的配置项:那么对于.ini文件,在python中可以借助与configpaerser库进行读写。

configparser库相关的源码分析:

对于读取ini文件需要生成ConfigParser类的对象,ConfigParser类是继承RawConfigParser类。
在这里插入图片描述
ConfigParser类的对象有read_file()函数,参数需要传入File对象,file对象可以open()函数生成,当然f不仅可以传入File对象,但必须是可迭代的对象,The ‘f’ argument must be iterable.
在这里插入图片描述
get 函数就是获取.ini中的option配置项,section是部分,每个section部分都有若干的option配置项。
在这里插入图片描述
pymysql加载ini文件配置项,具体代码展示:

import pymysql
from pymysql import Connection
import configparserdb_config = configparser.ConfigParser()
db_config.read_file(open('mysql_db.ini', encoding='utf-8', mode='rt'))conn: Connection = pymysql.connect(host=db_config.get('mysql', 'host'), # 连接名称,默认127.0.0.1user=db_config.get('mysql', 'user'), # 用户名passwd=db_config.get('mysql', 'passwd'), # 密码port=int(db_config.get('mysql', 'port')), # 端口,默认为3306db=db_config.get('mysql', 'db'), # 数据库名称charset=db_config.get('mysql', 'charset'), # 字符编码
)
print(conn)

1.4 操作cursor插入数据

conn.cursor() : 获取游标

要想操作数据库,光连接数据是不够的,必须拿到操作数据库的游标,才能进行后续的操作,比如读取数据、添加数据。通过获取到的数据库连接实例conn下的cursor()方法来创建游标。游标用来接收返回结果。

import pymysql
# 打开数据库连接
conn = pymysql.connect('localhost', user = "root", passwd = "123456", db = "testdb")
# 获取游标
cursor = conn.cursor()
print(cursor)

说明:cursor返回一个游标实例对象,其中包含了很多操作数据的方法,比如执行sql语句。源码展示如下:
在这里插入图片描述
执行sql语句execute和executemany

函数作用:执行单条的sql语句,执行成功后返回受影响的行数
在这里插入图片描述
execute 参数说明:

query:要执行的sql语句,字符串类型

args:可选的序列或映射,用于query的参数值。如果args为序列,query中必须使用%s做占位符;如果args为映射,query中必须使用%(key)s做占位符

在这里插入图片描述
函数作用:批量执行sql语句,比如批量插入数据,执行成功后返回受影响的行数

参数说明:

query:要执行的sql语句,字符串类型

args:嵌套的序列或映射,用于query的参数值

insert = cur.execute("insert into user values(1,'tom',18)")
print('添加语句受影响的行数:',insert)

execute和executemany 注意:


  1. 数据库性能瓶颈很大一部份就在于网络IO和磁盘IO,将多个sql语句放在一起,只执行一次IO,可以有效的提升数据库性能。【推荐此方法】

  2. 用executemany()方法一次性批量执行sql语句,固然很好,但是当数据一次传入过多到server端,可能造成server端的buffer溢出,也可能产生一些意想不到的麻烦。所以,合理、分批次使用executemany是个合理的办法

# 另一种插入数据的方式,通过字符串传入值
sql = "insert into user values(%s,%s,%s)"
insert = cur.executemany(sql,[(4,'wen',20),(5,'tom',10),(6,'test',30)])
print('批量插入返回受影响的行数:',insert)

注意:批量插入多条sql语句采用的是executemany(sql, args)函数,返回受影响的行数。args参数是一个包含多个元组的列表,每个元组对应一条mysql中的一条数据。这里的%s不需要加引号,否则插入数据的数据会类型错误。



1.5 操作cursor查询数据

pymysql 查询数据

使用execute()函数得到的只是受影响的行数,并不能真正拿到查询的内容。cursor对象还提供了3种提取数据的方法:fetchone、fetchmany、fetchall.。每个方法都会导致游标动,所以必须注意游标的位置。

cursor.fetchone() : 获取游标所在处的一行数据,返回元组,没有返回None

cursor.fetchmany(size) : 接受size行返回结果行。如果size大于返回的结果行的数量,则会返回cursor.arraysize条数据。

cursor. fetchall() : 接收全部的返回结果行。

cur = conn.cursor()cur.execute("select * from user;")
while True:res = cur.fetchone()if res is None:# 表示已经取完结果集breakprint(res)
cur.close() # 关闭查询游标
conn.commit() # 事务的提交
conn.close() # 查询完毕,需要关闭连接,释放计算机资源
print('sql执行成功')

注意:从execute()函数的查询结果中取数据,以元组的形式返回游标所在处的一条数据,如果游标所在处没有数据,将返回空元组,该数据执行一次,游标向下移动一个位置。fetchone()函数必须跟exceute()函数结合使用,并且在exceute()函数之后使用


cursor.fetchmany(size):接受size行返回结果行。如果size大于返回的结果行的数量,则会返回cursor.arraysize条数据。

# 获取游标
cur = conn.cursor()cur.execute("select * from user")
# 取3条数据
resTuple = cur.fetchmany(1)
print(type(resTuple))
for res in resTuple:print(res)cur.close() # 关闭查询游标
conn.commit() # 事务的提交
conn.close() # 查询完毕,需要关闭连接,释放计算机资源
print('sql执行成功')

注意:从exceute()函数结果中获取游标所在处的size条数据,并以元组的形式返回,元组的每一个元素都也是一个由一行数据组成的元组,如果size大于有效的结果行数,将会返回cursor.arraysize条数据,但如果游标所在处没有数据,将返回空元组。查询几条数据,游标将会向下移动几个位置。fetmany()函数必须跟exceute()函数结合使用,并且在exceute()函数之后使用


cursor. fetchall() : 接收全部的返回结果行

cur = conn.cursor()cur.execute("select * from user")
# 取所有数据
resTuple = cur.fetchall()
print(type(resTuple))
print("共%d条数据" % len(resTuple))cur.close() # 关闭查询游标
conn.commit() # 事务的提交
conn.close() # 查询完毕,需要关闭连接,释放计算机资源

注意:获取游标所在处开始及以下所有的数据,并以元组的形式返回,元组的每一个元素都也是一个由一行数据组成的元组,如果游标所在处没有数据,将返回空元组。执行完这个方法后,游标将移动到数据库表的最后.



1.6 操作cursor修改数据

代码示例:操作cursor游标进行更新单条数据

cur = conn.cursor()# 更新一条数据
update = cur.execute("update user set pwd='hello' where name='wrist'")
print('修改后受影响的行数为:', update)
# 查询一条数据
cur.execute('select * from user where name="wrist";')
print(cur.fetchone())
cur.close()
conn.commit()
conn.close()
print('sql执行成功')

代码示例:操作cursor游标更新多条数据

# 获取游标
cur = conn.cursor()
# 更新前查询所有数据
cur.execute("select * from user where name in ('唤醒手腕','蜡笔小新');")
print('更新前的数据为:')
for res in cur.fetchall():print(res)# 更新2条数据
sql = "update user set age=%s where name=%s"
update = cur.executemany(sql, [(15, '唤醒手腕'), (18, '蜡笔小新')])# 更新2条数据后查询所有数据
cur.execute("select * from user where name in ('唤醒手腕','蜡笔小新');")
print('更新后的数据为:')
for res in cur.fetchall():print(res)cur.close()
conn.commit()
conn.close()
print('sql执行成功')

1.7 操作cursor删除数据

代码示例:删除单条数据

# 获取游标
cur = conn.cursor()# 删除前查询所有数据
cur.execute("select * from user;")
print('删除前的数据为:')
for res in cur.fetchall():print(res)print('*' * 40)
# 删除1条数据
cur.execute("delete from user where id=1")# 删除后查询所有数据
cur.execute("select * from user;")
print('删除后的数据为:')
for res in cur.fetchall():print(res)
cur.close()
conn.commit()
conn.close()
print('sql执行成功')

代码示例:删除多条数据

cur = conn.cursor()
# 删除前查询所有数据
cur.execute("select * from user;")
print('删除前的数据为:')
for res in cur.fetchall():print(res)print('*' * 40)
# 删除2条数据
sql = "delete from user where id = %s"
cur.executemany(sql, [(3), (4)])# 删除后查询所有数据
cur.execute("select * from user;")
print('删除后的数据为:')
for res in cur.fetchall():print(res)
cur.close()
conn.commit()
conn.close()
print('sql执行成功')

1.8 pymysql常见事务操作

事务:一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务 ( 例如银行账户转账业务,该业务就是一个最小的工作单元 )

事务四大特征(ACID):

原子性(A):事务是最小单位,不可再分

一致性(C):事务要求所有的DML语句操作的时候,必须保证同时成功或者同时失败

隔离性(I):事务A和事务B之间具有隔离性

持久性(D):是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)


开启事务:Start Transaction 事务结束:End Transaction 提交事务:Commit Transaction
回滚事务:Rollback Transaction


回滚事务的案例操作:

import pymysql# 打开数据库连接
conn = pymysql.connect('localhost', 'root', '123456')
conn.select_db('pythondb')
# 获取游标
cur = conn.cursor()# 修改前查询所有数据
cur.execute("select * from user;")
print('修改前的数据为:')
for res in cur.fetchall():print(res)# 更新表中第1条数据
cur.execute("update user set name='唤醒手腕' where id=5")# 修改后查询所有数据
cur.execute("select * from user;")
print('修改后的数据为:')
for res in cur.fetchall():print(res)# 回滚事务
conn.rollback()
cur.execute("select * from user;")
print('回滚事务后的数据为:')
for res in cur.fetchall():print(res)cur.close()
conn.commit()
conn.close()
print('sql执行成功')

2. Python操作Redis数据库


3. Python操作Mongodb数据库


推荐阅读
author-avatar
faihiwang
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有