【Python pymysql】

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-28 15:27:53

原文: http://blog.gqylpy.com/gqy/257

目录

关于sql注入

用户存在,绕过密码

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

解决sql注入问题

commit()

查询数据库

fetchone()

fetchall()

fetchmany()

> 补充: >
> > 建立链接时间过长后会自动断开链接,可像下面这样解决: > ```python > 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:zykpwd: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行数

表内容如下:
![在这里插入图片描述](http://blog.gqylpy.com/media/ai/2019-03/a9d04dbf-2fee-42ac-89e3-4668738730c0.png)

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'}]"""

 

 



人生中不可避免的定律

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

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

定律三:担心定律
你越是担心的事情越有可能发生.

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

定律五:堵住定律
有很多越是输不起的人,越是喜欢下大赌注.

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

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

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

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

 

年轻本无价,一身碌碌无为
让无价变为了低价,你应该珍惜自己的机会.

原文: http://blog.gqylpy.com/gqy/257

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!