【Python pymysql】
"
目录
补充:
建立链接时间过长后会自动断开链接,可像下面这样解决:
conn.ping(reconnect=True)
检查链接是否还存在,参数
reconnect=True表示如果链接已不存在,则重新建立链接
补充:
# 回滚,通常用于事务 conn.rollback()
pymysql模块用于在Python程序中操作数据库.
该模块本质是一个套接字客户端软件.
Windows安装命令:pip3 install pymysql
基本使用:
-
# 准备数据库、数据和远程用户:
-
-
mysql> select * from blog.userinfo;
-
+----+------+-----+
-
| id | name | pwd |
-
+----+------+-----+
-
| 1 | zyk | ___ |
-
+----+------+-----+
-
1 row in set (0.00 sec)
-
-
mysql> show grants for 'zyk'@'%';
-
+------------------------------------------+
-
| Grants for zyk@% |
-
+------------------------------------------+
-
| GRANT ALL PRIVILEGES ON *.* TO 'zyk'@'%' |
-
+------------------------------------------+
-
1 row in set (0.00 sec)
-
# 实现:使用Python程序实现用户登陆,如果用户存在则登陆成功
-
-
import pymysql
-
-
user, pwd = input('user:'), input('pwd:')
-
-
# 1. 连接数据库
-
conn = pymysql.connect(
-
host='127.0.0.1',
-
port=3306,
-
user='zyk',
-
password='user@zyk',
-
db='blog', # 要连接的数据库名称
-
charset='utf8' # 要连接的数据库编码
-
)
-
-
# 2. 创建游标
-
cursor = conn.cursor()
-
-
-
# 3. 执行sql语句
-
sql = "select name,pwd from userinfo where name='%s' and pwd='%s'" % (user, pwd)
-
-
result = cursor.execute(sql) # 返回sql查询成功的记录数目(查到一条数据后便停止查询)
-
# print(result) # 即:成功返回1,否则0
-
-
-
# 4. 关闭
-
cursor.close() # 关闭游标
-
conn.close() # 关闭连接
-
-
print('log in successfully!') if result else print('logon failure!')
关于sql注入
补充:最新版本的pymysql已经不能sql注入了,只要加了 "--" 就会报错.
用户存在,绕过密码
利用sql语句中的注释(--),注释掉密码的部分.
-
import pymysql
-
-
user, pwd = input('user:'), input('pwd:')
-
-
# 1. 连接数据库
-
conn = pymysql.connect(
-
host='127.0.0.1',
-
port=3306,
-
user='zyk',
-
password='user@zyk',
-
db='blog', # 要连接的数据库名称
-
charset='utf8' # 要连接的数据库编码
-
)
-
-
# 2. 创建游标
-
cursor = conn.cursor()
-
-
-
# 3. 执行sql语句
-
# sql = "select name,pwd from userinfo where name='%s' and pwd='%s'" % (user, pwd)
-
-
# 用户存在,绕过密码
-
sql = "select name,pwd from userinfo where name='%s' -- abc' and pwd='%s'" % (user, pwd) # 注意:--后面要有一个空格,'abc'为任意字符,后面还要加个单引号
-
print(sql)
-
-
result = cursor.execute(sql) # 返回sql查询成功的记录数目
-
# print(result) # 即:成功返回1,否则0
-
-
-
# 4. 关闭
-
cursor.close() # 关闭游标
-
conn.close() # 关闭连接
-
-
-
print('log in successfully!') if result else print('logon failure!')
-
-
-
-
"""
-
代码输出如下:
-
-
user:zyk
-
pwd:
-
select name,pwd from userinfo where name='zyk' -- abc' and pwd=''
-
log in successfully!
-
"""
可见,我们只输入了用户名,并没有输入密码(密码被注释掉了),依然显示登陆成功.
用户不存在,绕过用户与密码
利用or语法,添加一条结果为True的语句,并注释掉密码的部分.
-
import pymysql
-
-
user, pwd = input('user:'), input('pwd:')
-
-
# 1. 连接数据库
-
conn = pymysql.connect(
-
host='127.0.0.1',
-
port=3306,
-
user='zyk',
-
password='user@zyk',
-
db='blog', # 要连接的数据库名称
-
charset='utf8' # 要连接的数据库编码
-
)
-
-
# 2. 创建游标
-
cursor = conn.cursor()
-
-
-
# 3. 执行sql语句
-
# sql = "select name,pwd from userinfo where name='%s' and pwd='%s'" % (user, pwd)
-
-
# 用户不存在,绕过用户与密码
-
sql = "select name,pwd from userinfo where name='%s' or 1=1 -- abc' and pwd='%s'" % (user, pwd)
-
print(sql)
-
-
result = cursor.execute(sql) # 返回sql查询成功的记录数目
-
# print(result) # 即:成功返回1,否则0
-
-
-
# 4. 关闭
-
cursor.close() # 关闭游标
-
conn.close() # 关闭连接
-
-
-
print('log in successfully!') if result else print('logon failure!')
-
-
-
-
"""
-
代码输出如下:
-
-
user:
-
pwd:
-
select name,pwd from userinfo where name='' or 1=1 -- abc' and pwd=''
-
log in successfully!
-
"""
可见,我们并为输入用户名和密码,依然显示登陆成功.
解决sql注入问题
pymysql模块自带解决sql注入的问题,只要我们按照pymysql模块的规定就行.
-
import pymysql
-
-
user, pwd = input('user:'), input('pwd:')
-
-
# 1. 连接数据库
-
conn = pymysql.connect(
-
host='127.0.0.1',
-
port=3306,
-
user='zyk',
-
password='user@zyk',
-
db='blog', # 要连接的数据库名称
-
charset='utf8' # 要连接的数据库编码
-
)
-
-
# 2. 创建游标
-
cursor = conn.cursor()
-
-
-
# 3. 执行sql语句
-
# sql = "select name,pwd from userinfo where name='%s' and pwd='%s'" % (user, pwd)
-
# result = cursor.execute(sql) # 返回sql查询成功的记录数目
-
# print(result) # 即:成功返回1,否则0
-
-
# 改写为(execute帮我们拼接字符串,我们无需且一定不能再为%s加引号)
-
sql = 'select name,pwd from userinfo where name=%s and pwd=%s'
-
-
# 改写为(用agrs参数传入用户名及密码)
-
result = cursor.execute(sql, [user, pwd])
-
-
-
# 4. 关闭
-
cursor.close() # 关闭游标
-
conn.close() # 关闭连接
-
-
-
print('log in successfully!') if result else print('logon failure!')
execute的arges参数可以接受list、tuple或dict:
如果args是一个列表或元组,%s可以用作查询中的占位符。
如果args是一个dict, %(name)s可以用作查询中的占位符。
-
# arges参数为dict时的写法:
-
sql = 'select name,pwd from userinfo where name=%(name)s and pwd=%(pwd)s'
-
result = cursor.execute(sql, {'name': user, 'pwd': pwd})
commit()
在数据库里增、删、改,只是在内存中操作,所以必须要进行提交,否则插入的数据不但不会生效,还会影响到自增id.
增
-
import pymysql
-
-
user, pwd = input('user:'), input('pwd:')
-
-
-
conn = pymysql.connect(
-
host='127.0.0.1',
-
port=3306,
-
user='zyk',
-
password='user@zyk',
-
db='blog', # 要连接的数据库名称
-
charset='utf8' # 要连接的数据库编码
-
)
-
-
# 创建游标
-
cursor = conn.cursor()
-
-
-
# 增
-
sql = 'insert into userinfo(name, pwd) values (%s, %s)'
-
effect_row = cursor.execute(sql,(user, pwd))
-
print(effect_row) # 返回增加的记录数
-
-
# 同时插入多条数据:executemany()
-
# effect_row = cursor.executemany(sql, [("张三", '123'), ("李四", '456')])
-
-
-
# 一定要记得提交
-
conn.commit()
-
-
-
# 关闭
-
cursor.close()
-
conn.close()
改
-
import pymysql
-
-
new_name = input('>>> ')
-
-
conn = pymysql.connect(
-
host='127.0.0.1',
-
port=3306,
-
user='zyk',
-
password='user@zyk',
-
db='blog', # 要连接的数据库名称
-
charset='utf8' # 要连接的数据库编码
-
)
-
-
# 创建游标
-
cursor = conn.cursor()
-
-
-
# 改
-
sql = "update userinfo set name=%s where name='zyk'"
-
effect_row = cursor.execute(sql, new_name)
-
print(effect_row) # 返回修改的记录数
-
-
# 一定要记得提交
-
conn.commit()
-
-
-
# 关闭
-
cursor.close()
-
conn.close()
删
-
import pymysql
-
-
conn = pymysql.connect(
-
host='127.0.0.1',
-
port=3306,
-
user='zyk',
-
password='user@zyk',
-
db='blog', # 要连接的数据库名称
-
charset='utf8' # 要连接的数据库编码
-
)
-
-
cursor = conn.cursor()
-
-
-
# 删
-
sql = "delete from userinfo where name='张三' or name='李四'" # 同时删除多条记录
-
effect_row = cursor.execute(sql)
-
print(effect_row) # 返回删除的记录数
-
-
# 一定要记得提交
-
conn.commit()
-
-
-
# 关闭
-
cursor.close()
-
conn.close()
查询数据库
- fetchone() # 获取下一行数据,第一次为首行
- fetchall() # 获取所有行数据
- fetchmany(4) # 获取4行数
表内容如下:

fetchone()
-
import pymysql
-
-
# 连接数据库
-
conn = pymysql.connect(
-
host='localhost',
-
port=3306,
-
user='zyk',
-
password='user@zyk',
-
db='blog',
-
charset='utf8'
-
)
-
-
# 创建游标
-
cursor = conn.cursor()
-
-
-
# 执行sql语句
-
sql = 'select * from userinfo'
-
cursor.execute(sql)
-
-
-
# 查询第一行数据
-
row = cursor.fetchone()
-
print(row)
-
-
# 查询第二行数据
-
row = cursor.fetchone()
-
print(row)
-
-
-
# 关闭
-
cursor.close()
-
conn.close()
-
-
-
-
"""
-
输出:
-
-
(1, 'zyk', '___')
-
(2, '张三', '123')
-
"""
如上:在获取行数据的时候,可以理解为开始。有一个行指针指向第一行,获取一行,他就向下移动一行。所以当行指针移动到最后一行时,便无法在获取到数据了(None)。此时我们可以使用如下方法来移动行指针:
- cursor.scroll(1, mode='relative') # 相对当前位置移动
- cursor.scroll(2, mode='absolute') # 相对绝对位置移动
值1为移动的行数,relative:可指定负数(向上移动);adsolute:0为第一行;
mode指定的是相对于当前行移动还是相对于首行移动.
fetchall()
-
import pymysql
-
-
# 连接数据库
-
conn = pymysql.connect(
-
host='localhost',
-
port=3306,
-
user='zyk',
-
password='user@zyk',
-
db='blog',
-
charset='utf8'
-
)
-
-
# 创建游标
-
cursor = conn.cursor()
-
-
-
# 执行sql语句
-
sql = 'select * from userinfo'
-
cursor.execute(sql)
-
-
-
# 获取所有数据
-
rows = cursor.fetchall()
-
print(rows)
-
-
-
# 关闭
-
cursor.close()
-
conn.close()
-
-
-
-
"""
-
输出:
-
-
((1, 'zyk', '___'), (2, '张三', '123'), (3, '李四', '456'))
-
"""
默认情况下,我们获取到的返回值是元组,可使用以下方式来返回字典:
-
# 在实例化时,将属性cursor设置为:
-
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
fetchmany()
-
import pymysql
-
-
# 连接数据库
-
conn = pymysql.connect(
-
host='localhost',
-
port=3306,
-
user='zyk',
-
password='user@zyk',
-
db='blog',
-
charset='utf8'
-
)
-
-
# 创建游标
-
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
-
-
-
# 执行sql语句
-
sql = 'select * from userinfo'
-
cursor.execute(sql)
-
-
-
# 获取2条数据
-
rows = cursor.fetchmany(2)
-
print(rows)
-
-
-
# 如果此时想要再获取已经获取过的数据,就需要移动行指针
-
cursor.scroll(0, mode='absolute') # 移动到第一行
-
-
rows = cursor.fetchall()
-
print(rows)
-
-
-
# 关闭
-
cursor.close()
-
conn.close()
-
-
-
-
"""
-
输出:
-
-
[{'id': 1, 'name': 'zyk', 'pwd': '___'}, {'id': 2, 'name': '张三', 'pwd': '123'}]
-
[{'id': 1, 'name': 'zyk', 'pwd': '___'}, {'id': 2, 'name': '张三', 'pwd': '123'}, {'id': 3, 'name': '李四', 'pwd': '456'}]
-
"""
人生中不可避免的定律
定律一:财富定律
勤劳不一定能够致富,但懒惰一定不能致富.
定律二:忙碌定律
人可以为了自己的梦想而去忙碌,但不能因为你忙碌而失去梦想.
定律三:担心定律
你越是担心的事情越有可能发生.
定律四:执着定律
任何的事情都不可过分执着,无论是风光还是难堪这些都会过去.
定律五:堵住定律
有很多越是输不起的人,越是喜欢下大赌注.
定律六:目标定律
目标太多,最后只会是失去目标,知道自己想要什么的人,能比都想要的人更容易成功.
定律七:方向定律
如果一个人不知道自己要向往哪个码头,那么不管什么风都不会是顺风.
定律八:诱惑定律
凡是抵挡不住诱惑的人,十之八九是没有经历过诱惑的人,这与诱惑大小无关.
定律九:时间定律
时间就是生命,对于男人来说是积累,对于女人来说是消耗.
年轻本无价,一身碌碌无为
让无价变为了低价,你应该珍惜自己的机会.
"
【Python pymysql】的更多相关文章
- 【Python数据分析】Python3多线程并发网络爬虫-以豆瓣图书Top250为例
基于上两篇文章的工作 [Python数据分析]Python3操作Excel-以豆瓣图书Top250为例 [Python数据分析]Python3操作Excel(二) 一些问题的解决与优化 已经正确地实现 ...
- 【Python数据分析】Python3操作Excel(二) 一些问题的解决与优化
继上一篇[Python数据分析]Python3操作Excel-以豆瓣图书Top250为例 对豆瓣图书Top250进行爬取以后,鉴于还有一些问题没有解决,所以进行了进一步的交流讨论,这期间得到了一只尼玛 ...
- 利用Dnspod api批量更新添加DNS解析【python脚本】 - 推酷
利用Dnspod api批量更新添加DNS解析[python脚本] - 推酷 undefined
- 【python进阶】详解元类及其应用2
前言 在上一篇文章[python进阶]详解元类及其应用1中,我们提到了关于元类的一些前置知识,介绍了类对象,动态创建类,使用type创建类,这一节我们将继续接着上文来讲~~~ 5.使⽤type创建带有 ...
- 【python进阶】Garbage collection垃圾回收2
前言 在上一篇文章[python进阶]Garbage collection垃圾回收1,我们讲述了Garbage collection(GC垃圾回收),画说Ruby与Python垃圾回收,Python中 ...
- 【python进阶】深入理解系统进程2
前言 在上一篇[python进阶]深入理解系统进程1中,我们讲述了多任务的一些概念,多进程的创建,fork等一些问题,这一节我们继续接着讲述系统进程的一些方法及注意点 multiprocessing ...
- 【python图像处理】图像的缩放、旋转与翻转
[python图像处理]图像的缩放.旋转与翻转 图像的几何变换,如缩放.旋转和翻转等,在图像处理中扮演着重要的角色,python中的Image类分别提供了这些操作的接口函数,下面进行逐一介绍. 1.图 ...
- 【Python 开发】Python目录
目录: [Python开发]第一篇:计算机基础 [Python 开发]第二篇 :Python安装 [Python 开发]第三篇:python 实用小工具
- 【Python教程】《零基础入门学习Python》(小甲鱼)
[Python教程]<零基础入门学习Python>(小甲鱼) 讲解通俗易懂,诙谐. 哈哈哈. https://www.bilibili.com/video/av27789609
随机推荐
- 利用Cadence PCB SI分析特性阻抗变化因素
1.概要 在进行PCB SI的设计时,理解特性阻抗是非常重要的.这次,我们对特性阻抗进行基础说明之外,还说明Allegro的阻抗计算原理以及各参数和阻抗的关系. 2.什么是特性阻抗? 2.1 传送线路 ...
- 接口自动化框架(Pytest,Allure,Yaml)
框架链接:https://www.jianshu.com/p/e31c54bf15ee 目前是基于他的框架做了些改动(主要是session.action()和json格式传参). 后续优化,应该主要思 ...
- tp5 使用phpword 替换word模板并利用com组件转换pdf
tp5 使用phpword 替换word模板并利用com组件转换pdf 一.首先composer安装PHPword,就不多说了 二.然后是把模板中要替换的部分用变量代替 三.把原始的模板文件放入项 ...
- mysql查询速度慢的分析和解决
一.定位执行慢的sql,如2秒内没执行完的抽取出来 show engines;查看慢查询时间show variables like 'slow%';查看设置多久是慢查询show variables l ...
- Virtual Judge HDU 1241 Oil Deposits
八方向 深搜 #include <iostream> #include<cstdio> #include<cstdlib> #include<algori ...
- JavaScript.Array.some() 方法用法
定义和用法:some() 方法用于检测数组中的元素是否满足指定条件(函数提供). some() 方法会依次执行数组的每个元素: 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检 ...
- 【转载】Spring MVC入门
转自:http://www.importnew.com/15141.html MVC框架是什么 模型-视图-控制器(MVC)是一个众所周知的以设计界面应用程序为基础的设计模式.它主要通过分离模型.视图 ...
- 美多商城后台MIS系统部署之Nginx配置
先进入Nginx的配置文件中,进行配置. Nginx配置文件夹的区别: cd /etc/nginx/conf.d/ 创建.conf后缀的文件 /etc/nginx/sites-enabled 创 ...
- 【网易官方】极客战记(codecombat)攻略-地牢-辐射光环
关卡连接: https://codecombat.163.com/play/level/radiant-aura 骷髅,恐惧还是回避? 简介: 敬请期待! 默认代码 # 捡起发光石,让骷髅怪远离你一会 ...
- Reinforcement Learning,微信公众号:DRL学习
欢迎大家关注微信公众号:DRL学习,我们一起来学习强化学习和深度强化学习的算法及现状应用问题. 强化学习简单说就是学习如何最大化未来奖励的预期总和,以及agent学会在环境中做出的行动序列,其中随机状 ...