"

目录

关于sql注入

用户存在,绕过密码

用户不存在,绕过用户与密码

解决sql注入问题

commit()

查询数据库

fetchone()

fetchall()

fetchmany()

补充:

建立链接时间过长后会自动断开链接,可像下面这样解决:

conn.ping(reconnect=True)

检查链接是否还存在,参数reconnect=True 表示如果链接已不存在,则重新建立链接


补充:


  1. # 回滚,通常用于事务
  2. conn.rollback()

pymysql模块用于在Python程序中操作数据库.

该模块本质是一个套接字客户端软件.


Windows安装命令:pip3 install pymysql

基本使用:


  1. # 准备数据库、数据和远程用户:
  2. mysql> select * from blog.userinfo;
  3. +----+------+-----+
  4. | id | name | pwd |
  5. +----+------+-----+
  6. | 1 | zyk | ___ |
  7. +----+------+-----+
  8. 1 row in set (0.00 sec)
  9. mysql> show grants for 'zyk'@'%';
  10. +------------------------------------------+
  11. | Grants for zyk@% |
  12. +------------------------------------------+
  13. | GRANT ALL PRIVILEGES ON *.* TO 'zyk'@'%' |
  14. +------------------------------------------+
  15. 1 row in set (0.00 sec)

  1. # 实现:使用Python程序实现用户登陆,如果用户存在则登陆成功
  2. import pymysql
  3. user, pwd = input('user:'), input('pwd:')
  4. # 1. 连接数据库
  5. conn = pymysql.connect(
  6. host='127.0.0.1',
  7. port=3306,
  8. user='zyk',
  9. password='user@zyk',
  10. db='blog', # 要连接的数据库名称
  11. charset='utf8' # 要连接的数据库编码
  12. )
  13. # 2. 创建游标
  14. cursor = conn.cursor()
  15. # 3. 执行sql语句
  16. sql = "select name,pwd from userinfo where name='%s' and pwd='%s'" % (user, pwd)
  17. result = cursor.execute(sql) # 返回sql查询成功的记录数目(查到一条数据后便停止查询)
  18. # print(result) # 即:成功返回1,否则0
  19. # 4. 关闭
  20. cursor.close() # 关闭游标
  21. conn.close() # 关闭连接
  22. print('log in successfully!') if result else print('logon failure!')

关于sql注入

补充:最新版本的pymysql已经不能sql注入了,只要加了 "--" 就会报错.

用户存在,绕过密码

利用sql语句中的注释(--),注释掉密码的部分.


  1. import pymysql
  2. user, pwd = input('user:'), input('pwd:')
  3. # 1. 连接数据库
  4. conn = pymysql.connect(
  5. host='127.0.0.1',
  6. port=3306,
  7. user='zyk',
  8. password='user@zyk',
  9. db='blog', # 要连接的数据库名称
  10. charset='utf8' # 要连接的数据库编码
  11. )
  12. # 2. 创建游标
  13. cursor = conn.cursor()
  14. # 3. 执行sql语句
  15. # sql = "select name,pwd from userinfo where name='%s' and pwd='%s'" % (user, pwd)
  16. # 用户存在,绕过密码
  17. sql = "select name,pwd from userinfo where name='%s' -- abc' and pwd='%s'" % (user, pwd) # 注意:--后面要有一个空格,'abc'为任意字符,后面还要加个单引号
  18. print(sql)
  19. result = cursor.execute(sql) # 返回sql查询成功的记录数目
  20. # print(result) # 即:成功返回1,否则0
  21. # 4. 关闭
  22. cursor.close() # 关闭游标
  23. conn.close() # 关闭连接
  24. print('log in successfully!') if result else print('logon failure!')
  25. """
  26. 代码输出如下:
  27. user:zyk
  28. pwd:
  29. select name,pwd from userinfo where name='zyk' -- abc' and pwd=''
  30. log in successfully!
  31. """

可见,我们只输入了用户名,并没有输入密码(密码被注释掉了),依然显示登陆成功.

用户不存在,绕过用户与密码

利用or语法,添加一条结果为True的语句,并注释掉密码的部分.


  1. import pymysql
  2. user, pwd = input('user:'), input('pwd:')
  3. # 1. 连接数据库
  4. conn = pymysql.connect(
  5. host='127.0.0.1',
  6. port=3306,
  7. user='zyk',
  8. password='user@zyk',
  9. db='blog', # 要连接的数据库名称
  10. charset='utf8' # 要连接的数据库编码
  11. )
  12. # 2. 创建游标
  13. cursor = conn.cursor()
  14. # 3. 执行sql语句
  15. # sql = "select name,pwd from userinfo where name='%s' and pwd='%s'" % (user, pwd)
  16. # 用户不存在,绕过用户与密码
  17. sql = "select name,pwd from userinfo where name='%s' or 1=1 -- abc' and pwd='%s'" % (user, pwd)
  18. print(sql)
  19. result = cursor.execute(sql) # 返回sql查询成功的记录数目
  20. # print(result) # 即:成功返回1,否则0
  21. # 4. 关闭
  22. cursor.close() # 关闭游标
  23. conn.close() # 关闭连接
  24. print('log in successfully!') if result else print('logon failure!')
  25. """
  26. 代码输出如下:
  27. user:
  28. pwd:
  29. select name,pwd from userinfo where name='' or 1=1 -- abc' and pwd=''
  30. log in successfully!
  31. """

可见,我们并为输入用户名和密码,依然显示登陆成功.

解决sql注入问题

pymysql模块自带解决sql注入的问题,只要我们按照pymysql模块的规定就行.


  1. import pymysql
  2. user, pwd = input('user:'), input('pwd:')
  3. # 1. 连接数据库
  4. conn = pymysql.connect(
  5. host='127.0.0.1',
  6. port=3306,
  7. user='zyk',
  8. password='user@zyk',
  9. db='blog', # 要连接的数据库名称
  10. charset='utf8' # 要连接的数据库编码
  11. )
  12. # 2. 创建游标
  13. cursor = conn.cursor()
  14. # 3. 执行sql语句
  15. # sql = "select name,pwd from userinfo where name='%s' and pwd='%s'" % (user, pwd)
  16. # result = cursor.execute(sql) # 返回sql查询成功的记录数目
  17. # print(result) # 即:成功返回1,否则0
  18. # 改写为(execute帮我们拼接字符串,我们无需且一定不能再为%s加引号)
  19. sql = 'select name,pwd from userinfo where name=%s and pwd=%s'
  20. # 改写为(用agrs参数传入用户名及密码)
  21. result = cursor.execute(sql, [user, pwd])
  22. # 4. 关闭
  23. cursor.close() # 关闭游标
  24. conn.close() # 关闭连接
  25. print('log in successfully!') if result else print('logon failure!')

execute的arges参数可以接受list、tuple或dict:
如果args是一个列表或元组,%s可以用作查询中的占位符。

如果args是一个dict, %(name)s可以用作查询中的占位符。


  1. # arges参数为dict时的写法:
  2. sql = 'select name,pwd from userinfo where name=%(name)s and pwd=%(pwd)s'
  3. result = cursor.execute(sql, {'name': user, 'pwd': pwd})

commit()

在数据库里增、删、改,只是在内存中操作,所以必须要进行提交,否则插入的数据不但不会生效,还会影响到自增id.


  1. import pymysql
  2. user, pwd = input('user:'), input('pwd:')
  3. conn = pymysql.connect(
  4. host='127.0.0.1',
  5. port=3306,
  6. user='zyk',
  7. password='user@zyk',
  8. db='blog', # 要连接的数据库名称
  9. charset='utf8' # 要连接的数据库编码
  10. )
  11. # 创建游标
  12. cursor = conn.cursor()
  13. # 增
  14. sql = 'insert into userinfo(name, pwd) values (%s, %s)'
  15. effect_row = cursor.execute(sql,(user, pwd))
  16. print(effect_row) # 返回增加的记录数
  17. # 同时插入多条数据:executemany()
  18. # effect_row = cursor.executemany(sql, [("张三", '123'), ("李四", '456')])
  19. # 一定要记得提交
  20. conn.commit()
  21. # 关闭
  22. cursor.close()
  23. conn.close()


  1. import pymysql
  2. new_name = input('>>> ')
  3. conn = pymysql.connect(
  4. host='127.0.0.1',
  5. port=3306,
  6. user='zyk',
  7. password='user@zyk',
  8. db='blog', # 要连接的数据库名称
  9. charset='utf8' # 要连接的数据库编码
  10. )
  11. # 创建游标
  12. cursor = conn.cursor()
  13. # 改
  14. sql = "update userinfo set name=%s where name='zyk'"
  15. effect_row = cursor.execute(sql, new_name)
  16. print(effect_row) # 返回修改的记录数
  17. # 一定要记得提交
  18. conn.commit()
  19. # 关闭
  20. cursor.close()
  21. conn.close()


  1. import pymysql
  2. conn = pymysql.connect(
  3. host='127.0.0.1',
  4. port=3306,
  5. user='zyk',
  6. password='user@zyk',
  7. db='blog', # 要连接的数据库名称
  8. charset='utf8' # 要连接的数据库编码
  9. )
  10. cursor = conn.cursor()
  11. # 删
  12. sql = "delete from userinfo where name='张三' or name='李四'" # 同时删除多条记录
  13. effect_row = cursor.execute(sql)
  14. print(effect_row) # 返回删除的记录数
  15. # 一定要记得提交
  16. conn.commit()
  17. # 关闭
  18. cursor.close()
  19. conn.close()


查询数据库

  • fetchone()        # 获取下一行数据,第一次为首行
  • fetchall()        # 获取所有行数据
  • fetchmany(4)        # 获取4行数

表内容如下:

fetchone()


  1. import pymysql
  2. # 连接数据库
  3. conn = pymysql.connect(
  4. host='localhost',
  5. port=3306,
  6. user='zyk',
  7. password='user@zyk',
  8. db='blog',
  9. charset='utf8'
  10. )
  11. # 创建游标
  12. cursor = conn.cursor()
  13. # 执行sql语句
  14. sql = 'select * from userinfo'
  15. cursor.execute(sql)
  16. # 查询第一行数据
  17. row = cursor.fetchone()
  18. print(row)
  19. # 查询第二行数据
  20. row = cursor.fetchone()
  21. print(row)
  22. # 关闭
  23. cursor.close()
  24. conn.close()
  25. """
  26. 输出:
  27. (1, 'zyk', '___')
  28. (2, '张三', '123')
  29. """

如上:在获取行数据的时候,可以理解为开始。有一个行指针指向第一行,获取一行,他就向下移动一行。所以当行指针移动到最后一行时,便无法在获取到数据了(None)。此时我们可以使用如下方法来移动行指针:

  • cursor.scroll(1, mode='relative')        # 相对当前位置移动
  • cursor.scroll(2, mode='absolute')        # 相对绝对位置移动

值1为移动的行数,relative:可指定负数(向上移动);adsolute:0为第一行;

mode指定的是相对于当前行移动还是​相对于首行移动.​​​​​​

fetchall()


  1. import pymysql
  2. # 连接数据库
  3. conn = pymysql.connect(
  4. host='localhost',
  5. port=3306,
  6. user='zyk',
  7. password='user@zyk',
  8. db='blog',
  9. charset='utf8'
  10. )
  11. # 创建游标
  12. cursor = conn.cursor()
  13. # 执行sql语句
  14. sql = 'select * from userinfo'
  15. cursor.execute(sql)
  16. # 获取所有数据
  17. rows = cursor.fetchall()
  18. print(rows)
  19. # 关闭
  20. cursor.close()
  21. conn.close()
  22. """
  23. 输出:
  24. ((1, 'zyk', '___'), (2, '张三', '123'), (3, '李四', '456'))
  25. """

默认情况下,我们获取到的返回值是元组,可使用以下方式来返回字典:


  1. # 在实例化时,将属性cursor设置为:
  2. cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

fetchmany()


  1. import pymysql
  2. # 连接数据库
  3. conn = pymysql.connect(
  4. host='localhost',
  5. port=3306,
  6. user='zyk',
  7. password='user@zyk',
  8. db='blog',
  9. charset='utf8'
  10. )
  11. # 创建游标
  12. cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
  13. # 执行sql语句
  14. sql = 'select * from userinfo'
  15. cursor.execute(sql)
  16. # 获取2条数据
  17. rows = cursor.fetchmany(2)
  18. print(rows)
  19. # 如果此时想要再获取已经获取过的数据,就需要移动行指针
  20. cursor.scroll(0, mode='absolute') # 移动到第一行
  21. rows = cursor.fetchall()
  22. print(rows)
  23. # 关闭
  24. cursor.close()
  25. conn.close()
  26. """
  27. 输出:
  28. [{'id': 1, 'name': 'zyk', 'pwd': '___'}, {'id': 2, 'name': '张三', 'pwd': '123'}]
  29. [{'id': 1, 'name': 'zyk', 'pwd': '___'}, {'id': 2, 'name': '张三', 'pwd': '123'}, {'id': 3, 'name': '李四', 'pwd': '456'}]
  30. """


人生中不可避免的定律

定律一:财富定律

勤劳不一定能够致富,但懒惰一定不能致富.

定律二:忙碌定律

人可以为了自己的梦想而去忙碌,但不能因为你忙碌而失去梦想.

定律三:担心定律

你越是担心的事情越有可能发生.

定律四:执着定律

任何的事情都不可过分执着,无论是风光还是难堪这些都会过去.

定律五:堵住定律

有很多越是输不起的人,越是喜欢下大赌注.

定律六:目标定律

目标太多,最后只会是失去目标,知道自己想要什么的人,能比都想要的人更容易成功.

定律七:方向定律

如果一个人不知道自己要向往哪个码头,那么不管什么风都不会是顺风.

定律八:诱惑定律

凡是抵挡不住诱惑的人,十之八九是没有经历过诱惑的人,这与诱惑大小无关.

定律九:时间定律

时间就是生命,对于男人来说是积累,对于女人来说是消耗.

年轻本无价,一身碌碌无为

让无价变为了低价,你应该珍惜自己的机会.

"

【Python pymysql】的更多相关文章

  1. 【Python数据分析】Python3多线程并发网络爬虫-以豆瓣图书Top250为例

    基于上两篇文章的工作 [Python数据分析]Python3操作Excel-以豆瓣图书Top250为例 [Python数据分析]Python3操作Excel(二) 一些问题的解决与优化 已经正确地实现 ...

  2. 【Python数据分析】Python3操作Excel(二) 一些问题的解决与优化

    继上一篇[Python数据分析]Python3操作Excel-以豆瓣图书Top250为例 对豆瓣图书Top250进行爬取以后,鉴于还有一些问题没有解决,所以进行了进一步的交流讨论,这期间得到了一只尼玛 ...

  3. 利用Dnspod api批量更新添加DNS解析【python脚本】 - 推酷

    利用Dnspod api批量更新添加DNS解析[python脚本] - 推酷 undefined

  4. 【python进阶】详解元类及其应用2

    前言 在上一篇文章[python进阶]详解元类及其应用1中,我们提到了关于元类的一些前置知识,介绍了类对象,动态创建类,使用type创建类,这一节我们将继续接着上文来讲~~~ 5.使⽤type创建带有 ...

  5. 【python进阶】Garbage collection垃圾回收2

    前言 在上一篇文章[python进阶]Garbage collection垃圾回收1,我们讲述了Garbage collection(GC垃圾回收),画说Ruby与Python垃圾回收,Python中 ...

  6. 【python进阶】深入理解系统进程2

    前言 在上一篇[python进阶]深入理解系统进程1中,我们讲述了多任务的一些概念,多进程的创建,fork等一些问题,这一节我们继续接着讲述系统进程的一些方法及注意点 multiprocessing ...

  7. 【python图像处理】图像的缩放、旋转与翻转

    [python图像处理]图像的缩放.旋转与翻转 图像的几何变换,如缩放.旋转和翻转等,在图像处理中扮演着重要的角色,python中的Image类分别提供了这些操作的接口函数,下面进行逐一介绍. 1.图 ...

  8. 【Python 开发】Python目录

    目录: [Python开发]第一篇:计算机基础 [Python 开发]第二篇 :Python安装 [Python 开发]第三篇:python 实用小工具

  9. 【Python教程】《零基础入门学习Python》(小甲鱼)

    [Python教程]<零基础入门学习Python>(小甲鱼) 讲解通俗易懂,诙谐. 哈哈哈. https://www.bilibili.com/video/av27789609

随机推荐

  1. C语言-数组指针与指针数组

    1.思考 下面这些声明合法吗? int array[5]; int matrix[3][3]; int * pa = array; int * pm = matrix; 问题: array代表数组首元 ...

  2. nginx location匹配及rewrite规则

    location匹配规则 1. 实例 server{ location = \ { [配置A] } location / { [配置B] } location = /images/ { [配置C] } ...

  3. Vue路由跳转时显示空白页面,iview的使用

    最近在用iview做项目,需要实现登录,注册,忘记密码等功能.iview-admin本来就有登录功能,于是想照葫芦画瓢,实现登录界面的注册,忘记密码页面路由跳转. router.js里路由配置,刚开始 ...

  4. java_细节_windows7下记事本保存为utf-8格式的问题

    如果在win7下的记事本直接另存为utf-8格式,是带有dom的utf-8,所以处理的时候需要注意,因为第一个字符是"?",而且不可见

  5. apache 二级域名设置

    1. 你要拥有一个有泛域名解析的顶级域名,例如:test.com 在dns服务上设置,域名服务商都提供此服务 www.test.com      指向服务器IPtest.com          指向 ...

  6. 淘宝 Api 查询手机号

    https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13834782535 淘宝 Api 查询手机号

  7. Mongodb学习笔记(四)管理

    一.数据导出.导入 数据导入:mongoexport ./mongoimport -d 数据库 -c 集合 文件名 数据导出:mongoimport 参数说明: -d:指明使用的库,如text -c: ...

  8. 09day vi命令详解

    vi有三种模式(互相切换) 1. 命令模式 2. 插入模式(编辑模式) 3. 低行模式 三种模式的切换方法: 使用技巧 vi 文件信息 i --- 进入编辑模式 esc --- 退出编辑模式 :wq ...

  9. [爬坑日记] 安卓模拟器1903蓝屏 没开hyper-v

    先说解决方案: 我在升级完1903之后短短几个小时蓝屏了两次 还是不同原因,不由得开始怀疑这个版本的稳定性,随后发现只有启动安卓模拟器的时候必然蓝屏(还有一次蓝屏实在安装驱动的时候) 经过百度得知需要 ...

  10. ISR吞吐性能问题

    ISR大致可以分几类: Cisco 860.880.890 ISR1800 (fixed).1800 (modular).2800.3800 Series ISR1900.2900.3800.3900 ...