一、介绍

  之前都是通过MySQ自带的命令行客户端工具Mysql来操作数据库,那如何在Python程序中操作数据库呢?这就需要用到pymysql模块了。

  这个模块本质就是一个套接字客户端软件,使用前需要实现安装

pip3 install pymysql

二、链接、执行sql、关闭游标

  通过Navicat创建一个db9数据库并创建userinfo表

mysql> desc userinfo;
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user | char(16) | NO | | NULL | |
| pwd | char(20) | YES | | NULL | |
+-------+----------+------+-----+---------+----------------+ mysql> select * from userinfo;
+----+------+------+
| id | user | pwd |
+----+------+------+
| 1 | egon | 123 |
| 2 | alex | 456 |
+----+------+------+
"""
"""
# 登录数据库,允许远程访问
mysql> grant all on *.* to 'root'@'%' identified by '';
Query OK, 0 rows affected, 1 warning (0.01 sec) # 立即刷新数据库,配置立即生效
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

创建库表并授权

  mysql模块的基本使用:

# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang' import pymysql # 套接字 user = input('user>>:').strip()
pwd = input('pwd>>:').strip() # 建立链接
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
db='db9',
charset='utf8' # mysql指定utf-8的格式是没有杠的
) # 拿到游标
course=conn.cursor() # 执行完毕返回的结果集默认以元组显示 # 执行sql语句
sql = 'select * from userinfo where user = "%s" and pwd="%s"' % (user, pwd)
rows = course.execute(sql) # 游标的execute接口传入sql语句,返回sql查询成功的记录数 # 资源回收
course.close() # 关闭游标
conn.close() # 关闭连接 # 进行判断
if rows:
print('登录成功')
else:
print('登录失败')
"""
user>>:egon
pwd>>:123
登录成功
"""

三、execute()之sql注入

  注意:符号--会注释掉它之后的sql,正确的语法:--后至少有一个任意字符

# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang' # pip3 install pymysql
import pymysql # 套接字 user = input('user>>:').strip()
pwd = input('pwd>>:').strip() # 建立链接
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
db='db9',
charset='utf8' # mysql指定utf-8的格式是没有杠的
) # 拿到游标
course=conn.cursor() # 执行完毕返回的结果集默认以元组显示 # 执行sql语句
sql = 'select * from userinfo where user = "%s" and pwd="%s"' % (user, pwd)
print(sql) # 查看被注入的sql
rows = course.execute(sql) # 游标的execute接口传入sql语句,返回sql查询成功的记录数 # 资源回收
course.close() # 关闭游标
conn.close() # 关闭连接 # 进行判断
if rows:
print('登录成功')
else:
print('登录失败')
"""
user>>:egon" -- xxxx # 双"-"之后全都变为注释
pwd>>:123
select * from userinfo where user = "egon" -- xxxx" and pwd="123"
登录成功
""" # 不用输入密码直接登录,"和sql语句中的"拼接 , 或判断与1=1
# user>>:xxx" or 1=1 -- hahahwdda" and pwd=""
# pwd>>:
# select * from userinfo where user = "xxx" or 1=1 -- hahahwdda and pwd=""" and pwd=""
# 登录成功

sql注入案例

  根本原理:就根据程序的字符串拼接name='%s',我们输入一个xxx' -- haha,用我们输入的xxx加'在程序中拼接成一个判断条件name='xxx' -- haha'

  解决办法:

# 原来是我们对sql进行字符串拼接
# sql="select * from userinfo where name='%s' and password='%s'" %(user,pwd)
# print(sql)
# res=cursor.execute(sql) #改写为(execute帮我们做字符串拼接,我们无需且一定不能再为%s加引号了)
sql="select * from userinfo where name=%s and password=%s" #!!!注意%s需要去掉引号,因为pymysql会自动为我们加上
res=cursor.execute(sql,[user,pwd]) #pymysql模块自动帮我们解决sql注入的问题,只要我们按照pymysql的规矩来。
# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang' # pip3 install pymysql
import pymysql # 套接字 user = input('user>>:').strip()
pwd = input('pwd>>:').strip() # 建立链接
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
db='db9',
charset='utf8' # mysql指定utf-8的格式是没有杠的
) # 拿到游标
course=conn.cursor() # 执行完毕返回的结果集默认以元组显示 # 执行sql语句
# sql = 'select * from userinfo where user = "%s" and pwd="%s"' % (user, pwd)
# print(sql) # 查看被注入的sql sql = 'select * from userinfo where user = %s and pwd=%s'
rows = course.execute(sql, (user, pwd)) # 不使用字符串拼接,采用execute在后面传值的方式 # 资源回收
course.close() # 关闭游标
conn.close() # 关闭连接 # 进行判断
if rows:
print('登录成功')
else:
print('登录失败')
"""
user>>:xxx" or 1=1 -- hahahwdda" and pwd=""
pwd>>:
登录失败
"""

代码改造为防止sql注入

四、增、删、改:conn.commit()

  增、删、改的操作相似。以对表格添加记录为例。

# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang' import pymysql # 建立链接
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
db='db9',
charset='utf8' # mysql指定utf-8的格式是没有杠的
) # 拿游标
cursor=conn.cursor() # 执行sql
# 增删改
sql='insert into userinfo(user,pwd) values(%s,%s);'
# 单一操作
# res=cursor.execute(sql,("wxx","123")) #执行sql语句,返回sql影响成功的行数
# print(res) # 批量操作
cursor.executemany(sql,[('yxx',''), ('egon1',''), ('zurong','')]) conn.commit() # 注意:提交后记录才会插入成功
# 关闭链接
cursor.close()
conn.close()
"""
+----+--------+------+
| id | user | pwd |
+----+--------+------+
| 1 | egon | 123 |
| 2 | alex | 456 |
| 3 | hqs | 123 |
| 5 | wxx | 123 |
| 8 | yxx | 123 |
| 9 | egon1 | 123 |
| 10 | zurong | 123 |
+----+--------+------+
"""

五、查:fetchone,fetchmany,fetchall

# 建立链接
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
db='db9',
charset='utf8' # mysql指定utf-8的格式是没有杠的
) # 拿游标
cursor=conn.cursor() # 执行sql查询
rows = cursor.execute('select * from userinfo;') # 把sql发给服务端
# print(rows) # 显示的仅仅是受影响的行数 # 为了得到执行结果,需要使用fetchone()函数,一次得到一条服务端执行记录
print(cursor.fetchone())
print(cursor.fetchone())
"""
(1, 'egon', '123')
(2, 'alex', '456')
""" conn.commit() # 注意:提交后记录才会插入成功
# 关闭链接
cursor.close()
conn.close()

查看记录

  可以看到上面的记录没有字段信息,很难分辨数据具体属于哪个字段。因此需要在拿游标时,使用:cursor=conn.cursor(pymysql.cursors.DictCursor)  得到基于字典的游标。

conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
db='db9',
charset='utf8' # mysql指定utf-8的格式是没有杠的
) # 拿游标
cursor=conn.cursor(pymysql.cursors.DictCursor) # 基于字典的游标 # 执行sql查询
rows = cursor.execute('select * from userinfo;')
# print(cursor.fetchone())
# print(cursor.fetchone())
"""
{'id': 1, 'user': 'egon', 'pwd': '123'}
{'id': 2, 'user': 'alex', 'pwd': '456'}
""" # 一次取多个
print(cursor.fetchmany(3))
"""
[{'id': 1, 'user': 'egon', 'pwd': '123'}, {'id': 2, 'user': 'alex', 'pwd': '456'}, {'id': 3, 'user': 'hqs', 'pwd': '123'}]
""" # 全部取出
print(cursor.fetchall()) # 如果是和上面的和语句一起执行,则是取出id=3之后的数据
print(cursor.fetchall()) # 上一条取完所有数据,游标已经到了记录结尾,此次为空
"""
[{'id': 1, 'user': 'egon', 'pwd': '123'}, {'id': 2, 'user': 'alex', 'pwd': '456'}, {'id': 3, 'user': 'hqs', 'pwd': '123'}]
[{'id': 5, 'user': 'wxx', 'pwd': '123'}, {'id': 8, 'user': 'yxx', 'pwd': '123'}, {'id': 9, 'user': 'egon1', 'pwd': '123'}, {'id': 10, 'user': 'zurong', 'pwd': '123'}]
[]
""" conn.commit() # 注意:提交后记录才会插入成功
# 关闭链接
cursor.close()
conn.close()

  从上例中可以学习到fetchone,fetchmany,fetchall这三种方法的使用和区别。但是由此也看到,读取记录存在游标位置问题。

  相对绝对位置移动:cursor.scroll(3,mode='absolute')

  相对当前位置移动:cursor.scroll(3,mode='relative')

conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
db='db9',
charset='utf8' # mysql指定utf-8的格式是没有杠的
) # 拿游标
cursor=conn.cursor(pymysql.cursors.DictCursor) # 基于字典的游标 # 执行sql查询
rows = cursor.execute('select * from userinfo;')
print(cursor.fetchall()) # 先移动到最后
# 游标移动——相对绝对位置移动
cursor.scroll(2,mode='absolute') # 相对绝对位置移动——从结果最开始起到第2条数据结尾
print(cursor.fetchone())
print(cursor.fetchone())
"""
[{'id': 1, 'user': 'egon', 'pwd': '123'}, ...]
{'id': 3, 'user': 'hqs', 'pwd': '123'}
{'id': 5, 'user': 'wxx', 'pwd': '123'}
""" # 游标移动——相对当前位置移动
cursor.scroll(2,mode='relative') # 相对当前位置移动——从id=5这个结果开始,移动到id=9最后
print(cursor.fetchone())
print(cursor.fetchone())
"""
{'id': 10, 'user': 'zurong', 'pwd': '123'}
None # 没有数据了还查询,即返回None
""" conn.commit() # 注意:提交后记录才会插入成功
# 关闭链接
cursor.close()
conn.close()
"""
+----+--------+------+
| id | user | pwd |
+----+--------+------+
| 1 | egon | 123 |
| 2 | alex | 456 |
| 3 | hqs | 123 |
| 5 | wxx | 123 |
| 8 | yxx | 123 |
| 9 | egon1 | 123 |
| 10 | zurong | 123 |
+----+--------+------+
"""

六、获取插入的最后一条数据的自增ID

# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang' import pymysql
# conn=pymysql.connect(host='127.0.0.1',user='root',password='1234',database='egon')
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
db='db9',
charset='utf8' # mysql指定utf-8的格式是没有杠的
) cursor=conn.cursor() sql='insert into userinfo(user,pwd) values("xxx","123");'
rows=cursor.execute(sql)
print(cursor.lastrowid) # 插入之前id走到的数字(下一条即将插入的记录的id) conn.commit() cursor.close()
conn.close()
"""
11
+----+--------+------+
| id | user | pwd |
+----+--------+------+
| 1 | egon | 123 |
| 2 | alex | 456 |
| 3 | hqs | 123 |
| 5 | wxx | 123 |
| 8 | yxx | 123 |
| 9 | egon1 | 123 |
| 10 | zurong | 123 |
+----+--------+------+
"""

mysql五:pymysql模块的更多相关文章

  1. Python中操作mysql的pymysql模块详解

    Python中操作mysql的pymysql模块详解 前言 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持 ...

  2. MySQL之pymysql模块

    MySQL之pymysql模块   import pymysql #s链接数据库 conn = pymysql.connect( host = '127.0.0.1', #被连接数据库的ip地址 po ...

  3. 第二百七十九节,MySQL数据库-pymysql模块操作数据库

    MySQL数据库-pymysql模块操作数据库 pymysql模块是python操作数据库的一个模块 connect()创建数据库链接,参数是连接数据库需要的连接参数使用方式: 模块名称.connec ...

  4. (转)Python中操作mysql的pymysql模块详解

    原文:https://www.cnblogs.com/wt11/p/6141225.html https://shockerli.net/post/python3-pymysql/----Python ...

  5. mysql python pymysql模块 基本使用

    我们都是通过MySQL自带的命令行客户端工具mysql来操作数据库,那如何在python程序中操作数据库呢? 这就用到了pymysql模块,该模块本质就是一个套接字客户端软件,使用前需要事先安装 pi ...

  6. MySQL数据库-pymysql模块操作数据库

    pymysql模块是python操作数据库的一个模块 connect()创建数据库链接,参数是连接数据库需要的连接参数使用方式: 模块名称.connect() 参数: host=数据库ip port= ...

  7. Python3.7.1学习(七)mysql中pymysql模块详解(一)

    pymysql是纯用Python操作MySQL的模块,其使用方法和MySQLdb几乎相同.此次介绍mysql以及在python中如何用pymysql操作数据库, 以及在mysql中存储过程, 触发器以 ...

  8. Python操作MySQL:pymysql模块

    连接MySQL有两个模块:mysqldb和pymysql,第一个在Python3.x上不能用,所以我们学pymysql import pymysql # 创建连接 conn = pymysql.con ...

  9. mysql python pymysql模块 增删改查 插入数据 介绍 commit() execute() executemany() 函数

    import pymysql mysql_host = '192.168.0.106' port = 3306 mysql_user = 'root' mysql_pwd = ' encoding = ...

  10. mysql python pymysql模块 增删改查 查询 fetchone

    import pymysql mysql_host = '192.168.0.106' port = 3306 mysql_user = 'root' mysql_pwd = ' encoding = ...

随机推荐

  1. java开发系统内核:让内核从严重错误中恢复

    更详细的讲解和代码调试演示过程,请参看视频 用java开发C语言编译器 更详细的讲解和代码调试演示过程,请参看视频 如何进入google,算法面试技能全面提升指南 如果你对机器学习感兴趣,请参看一下链 ...

  2. SQL Server为啥使用了这么多内存?

    原文地址:http://support.microsoft.com/gp/anxin_techtip6/zh-cn SQL Server为啥使用了这么多内存? SQL Server的用户,常常会发现S ...

  3. php 利用 json 传递数组之中文乱码最新解决办法

    json好用,但是如果数据中有中文就会出乱子了,网上解决办法多半是设置utf-8编码或转换字符编码 以下是我的解决办法,利用php的urlencode.urldecode函数(其实也是一种转换编码吧) ...

  4. angularjs中向html页面添加内容节点元素代码段的两种方法

    第一种方式:原生JS向html页面添加内容节点元素代码段: <!DOCTYPE html> <html> <head> <meta charset=" ...

  5. mfix添加文件后重新生成configure文件

    mfix给了一些程序接口,大部分时候只用修改现有程序即可满足要求,这种情况不用修改configure文件,但是如果添加了新文件就需要做一些修改. 我用了Jian Cai的程序尝试了一下编译,该学者在2 ...

  6. Codeforces - 915E 离散化区间覆盖

    我一直以来都错认为离散化就是换个映射,其实还需要在离散值两端加上相差为1的值才能真正离散 不然看一下test3就知道 不过这个离散姿势太暴力,以至于我1000ms时限跑出998ms(其实是太懒没有删重 ...

  7. c#工具类之Bitmap缩放帮忙类

    using System.Drawing; using System.Drawing.Drawing2D; /// <summary> /// BitmapHelper /// </ ...

  8. PIE SDK波谱运算

    1.算法功能简介 波谱运算(Spectral Math)是一种灵活的波谱处理工具,可以用数学表达式或IDL程序对波谱曲线(以及选择的多波段图像)进行处理.波谱曲线可以来自一幅多波段图像的Z剖面.波谱库 ...

  9. 小众软件:Windows 下优化软件推荐—— Dism++ | 强迫症晚期患者福音 - 少数派

    Windows 下优化软件推荐—— Dism++ | 强迫症晚期患者福音 - 少数派 https://sspai.com/post/41992 官方网站免费下载

  10. 【CAD】创建多行文本

    下面为OBJECT-ARX创建多行文本的代码,记录 McDbMText* Mx::AddMText(IN McDbBlockTableRecord* pBlkRec, IN LPCTSTR pszCo ...