【Python pymysql】 -- 2019-08-08 18:01:58

原文: http://106.13.73.98/__/31/

目录

关于sql注入

用户存在,绕过密码

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

解决sql注入问题

commit()

查询数据库

fetchone()

fetchall()

fetchmany()

> 补充:
>

>
> 建立链接时间过长后会自动断开链接,可像下面这样解决:
> ```python
> 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 [email protected]% |
  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=‘[email protected]‘,
  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=‘[email protected]‘,
  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=‘[email protected]‘,
  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=‘[email protected]‘,
  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=‘[email protected]‘,
  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=‘[email protected]‘,
  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=‘[email protected]‘,
  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行数

表内容如下:

![在这里插入图片描述](http://106.13.73.98/media/ai/2019-03/a9d04dbf-2fee-42ac-89e3-4668738730c0.png)

fetchone()


  1. import pymysql
  2. # 连接数据库
  3. conn = pymysql.connect(
  4. host=‘localhost‘,
  5. port=3306,
  6. user=‘zyk‘,
  7. password=‘[email protected]‘,
  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=‘[email protected]‘,
  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=‘[email protected]‘,
  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. """



人生中不可避免的定律

定律一:财富定律

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

定律二:忙碌定律

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

定律三:担心定律

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

定律四:执着定律

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

定律五:堵住定律

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

定律六:目标定律

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

定律七:方向定律

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

定律八:诱惑定律

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

定律九:时间定律

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

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

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

原文: http://106.13.73.98/__/31/

原文地址:https://www.cnblogs.com/gqy02/p/11322805.html

时间: 2024-10-11 23:11:32

【Python pymysql】 -- 2019-08-08 18:01:58的相关文章

【Python 多进程】 -- 2019-08-16 20:08:07

原文: http://blog.gqylpy.com/gqy/228 " 一.模块介绍 multiprocess模快 仔细说来,multiprocess不是一个模块,而是python中的一个操作.管理进程的包,之所以叫multi是取自multiple的多功能的意思,这个包中几乎包含了和进程有关的所有子模块. multiprocess.Process模块 Process能够帮助我们创建子进程,以及对子进程的一些控制. 参数:def __init__(self, group=None, target

【Python pymysql】 -- 2019-08-11 19:26:12

原文: http://106.13.73.98/__/31/ 目录 关于sql注入 用户存在,绕过密码 用户不存在,绕过用户与密码 解决sql注入问题 commit() 增 改 删 查询数据库 fetchone() fetchall() fetchmany() > 补充: > > > 建立链接时间过长后会自动断开链接,可像下面这样解决: > ```python > conn.ping(reconnect=True) > ``` > 检查链接是否还存在,参数`

【Python Network】使用DOM生成XML

单纯的为DOM树添加结点. 1 #!/usr/bin/env python 2 # Generating XML with DOM - Chapter 8 - domgensample.py 3 4 from xml.dom import minidom, Node 5 6 doc = minidom.Document() 7 8 doc.appendChild(doc.createComment("Sample XML Document - Chapter 8 -")) 9 10 #

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

前言 在上一篇文章[python进阶]详解元类及其应用1中,我们提到了关于元类的一些前置知识,介绍了类对象,动态创建类,使用type创建类,这一节我们将继续接着上文来讲~~~ 5.使?type创建带有?法的类 最终你会希望为你的类增加?法.只需要定义?个有着恰当签名的函数并将 其作为属性赋值就可以了.添加实例?法 In [14]: def echo_bar(self):#定义了一个普通的函数 ...: print(self.bar) ...: In [15]: FooChild = type('

【python学习】8.异常

[python学习]8.异常 raise Exception: 抛出指定异常 try/except: 捕捉异常 except: 第一个参数是需要捕获的异常类型,可以是多个类型组成元组,第二个参数是捕获到的异常对象, raise: 抛出已经捕获的异常 else: 当没有捕获的异常时候执行 finally: 总会被执行 def test(): try: raise Exception("test") except (Exception), e: print "Exception&

【LeetCode】【Python题解】Pascal's Triangle

Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Return [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 要求输入一个整数,返回一个表示杨辉三角的数组.我的方法是计算通项公式,首先是编写阶乘函数,然后计算C00,C10,C11即可 利用Python 的map嵌套可以很简洁地实现,核心代码只有一行! class So

【LeetCode】【Python题解】Best Time to Buy and Sell Stock II

Say you have an array for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). Ho

【python爬虫】根据查询词爬取网站返回结果

最近在做语义方面的问题,需要反义词.就在网上找反义词大全之类的,但是大多不全,没有我想要的.然后就找相关的网站,发现了http://fanyici.xpcha.com/5f7x868lizu.html,还行能把"老师"-"学生","医生"-"病人"这样对立关系的反义词查出来. 一开始我想把网站中数据库中存在的所有的词语都爬出来(暗网爬虫),但是分析了url的特点: http://fanyici.xpcha.com/5f7x86

【python系列】SyntaxError:Missing parentheses in call to 'print'

打印python2和python3的区别 如上图所示,我的 PyCharm安装的是python3.6如果使用print 10会出现语法错误,这是python2.x和python3.x的区别所导致的. [python系列]SyntaxError:Missing parentheses in call to 'print'