zoukankan      html  css  js  c++  java
  • 【Python pymysql】

    "




    目录

    关于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. """


    人生中不可避免的定律

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

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

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

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

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

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

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

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

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

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

    "
  • 相关阅读:
    Kubernetes二进制文件下载链接
    Python 中取代 Printf 大法的工具
    Python 七步捉虫法
    改善 Python 程序的 91 个建议
    最全的 API 接口集合
    一个可能是世界上最全的 API 接口集合库开源项目
    优质中文NLP资源集合,做项目一定用得到!
    Flair:一款简单但技术先进的NLP库
    取代 Python 多进程!伯克利开源分布式框架 Ray
    使用 PyHamcrest 执行健壮的单元测试
  • 原文地址:https://www.cnblogs.com/zyk01/p/11375986.html
Copyright © 2011-2022 走看看