pymysql

​ 我们要学的pymysql就是用来在python程序中如何操作mysql,本质上就是一个套接字客户端,只不过这个套接字客户端是在python程序中用的,既然是客户端套接字,应该怎么用,是不是要连接服务端,并且和服务端进行通信啊,让我们来学习一下pymysql这个模块

安装

pip3 install pymysql

使用

我们通过一个登陆认证,也就是验证用户名和密码是否在用户表中存在来使用一下pymysql

首先我们创建一个用户表,名为userinfo表,其中有用户名(name)和密码字段(password),然后在表中存放一些数据。

然后在我们的python脚本中写上以下内容,就可以完成我们的登陆认证了

import pymysql
user=input('用户名: ').strip()
pwd=input('密码: ').strip() #链接,指定ip地址和端口,本机上测试时ip地址可以写localhost或者自己的ip地址或者127.0.0.1,然后你操作数据库的时候的用户名,密码,要指定你操作的是哪个数据库,指定库名,还要指定字符集。不然会出现乱码
conn=pymysql.connect(host='localhost',port=3306,user='root',password='123',database='student',charset='utf8') cursor=conn.cursor() #这就想到于mysql自带的那个客户端的游标mysql> 在这后面输入指令,回车执行 sql='select * from userinfo where name="%s" and password="%s"' %(user,pwd) res=cursor.execute(sql) #执行sql语句,返回sql查询成功的记录数目,是个数字,是受sql语句影响到的记录行数
#all_data=cursor.fetchall() #获取返回的所有数据,注意凡是取数据,取过的数据就没有了,结果都是元祖格式的
#many_data=cursor.fetchmany(3) #一下取出3条数据,
#one_data=cursor.fetchone() #按照数据的顺序,一次只拿一个数据,下次再去就从第二个取了,因为第一个被取出去了,取一次就没有了,结果也都是元祖格式的
if res:
print('登录成功')
else:
print('登录失败') cursor.close() #关闭游标
conn.close() #关闭连接

sql注入

所谓sql注入,就是通过将一些特殊符号写入到我们的sql语句中,使我们的sql语句失去了原有的作用。比如绕开我们的认证机制,在不知道用户名和密码的情况下完成登录。

基于上一节的示例,我们看一下sql注入怎么搞事情的。

以下还是上述示例的代码

import pymysql

conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='666',
database='crm',
charset='utf8'
) cursor = conn.cursor(pymysql.cursors.DictCursor)
uname = input('请输入用户名:')
pword = input('请输入密码:') sql = "select * from userinfo where username='%s' and password='%s';"%(uname,pword) res = cursor.execute(sql) #res我们说是得到的行数,如果这个行数不为零,说明用户输入的用户名和密码存在,如果为0说名存在,你想想对不 print(res) #如果输入的用户名和密码错误,这个结果为0,如果正确,这个结果为1
if res:
print('登陆成功')
else:
print('用户名和密码错误!')

但是我们来看下面的操作,如果将在输入用户名的地方输入一个 chao'空格然后--空格然后加上任意的字符串,就能够登陆成功,也就是只知道用户名的情况下,他就能登陆成功的情况:

uname = input('请输入用户名:')
pword = input('请输入密码:') sql = "select * from userinfo where username='%s' and password='%s';"%(uname,pword)
print(sql)
res = cursor.execute(sql) #res我们说是得到的行数,如果这个行数不为零,说明用户输入的用户名和密码存在,如果为0说名存在,你想想对不 print(res) #如果输入的用户名和密码错误,这个结果为0,如果正确,这个结果为1
if res:
print('登陆成功')
else:
print('用户名和密码错误!')
#运行看结果:居然登陆成功
请输入用户名:chao' -- xxx
请输入密码:
select * from userinfo where username='chao' -- xxx' and password='';
1
登陆成功

我们来分析一下:

此时uname这个变量等于什么,等于chao' -- xxx,然后我们来看我们的sql语句被这个字符串替换之后是个什么样子:
select * from userinfo where username='chao' -- xxx' and password=''; 其中chao后面的这个',在进行字符串替换的时候,我们输入的是chao',这个引号和前面的引号组成了一对,然后后面--在sql语句里面是注释的意思,也就是说--后面的sql语句被注释掉了。也就是说,拿到的sql语句是select * from userinfo where username='chao';然后就去自己的数据库里面去执行了,发现能够找到对应的记录,因为有用户名为chao的记录,然后他就登陆成功了,但是其实他连密码都不知道,只知道个用户名。。。,他完美的跳过了你的认证环节。

然后我们再来看一个例子,直接连用户名和密码都不知道,但是依然能够登陆成功的情况:

请输入用户名:xxx' or 1=1 -- xxxxxx
请输入密码:
select * from userinfo where username='xxx' or 1=1 -- xxxxxx' and password='';
3
登陆成功 我们只输入了一个xxx' 加or 加 1=1 加 -- 加任意字符串
看上面被执行的sql语句你就发现了,or 后面跟了一个永远为真的条件,那么即便是username对不上,但是or后面的条件是成立的,也能够登陆成功。

出现这样的问题,我们怎么解决的?通过pymysql给我们提供的execute方法可以解决,看示例:

之前我们的sql语句是这样写的:
sql = "select * from userinfo where username='%s' and password='%s';"%(uname,pword) 以后再写的时候,sql语句里面的%s左右的引号去掉,并且语句后面的%(uname,pword)这些内容也不要自己写了,按照下面的方式写
sql = "select * from userinfo where username=%s and password=%s;"
难道我们不传值了吗,不是的,我们通过下面的形式,在excute里面写参数:
#cursor.execute(sql,[uname,pword]) ,其实它本质也是帮你进行了字符串的替换,只不过它会将uname和pword里面的特殊字符给过滤掉。 看下面的例子:
uname = input('请输入用户名:') #输入的内容是:chao' -- xxx或者xxx' or 1=1 -- xxxxx
pword = input('请输入密码:') sql = "select * from userinfo where username=%s and password=%s;"
print(sql)
res = cursor.execute(sql,[uname,pword]) #res我们说是得到的行数,如果这个行数不为零,说明用户输入的用户名和密码存在,如果为0说名存在,你想想对不 print(res) #如果输入的用户名和密码错误,这个结果为0,如果正确,这个结果为1
if res:
print('登陆成功')
else:
print('用户名和密码错误!')
#看结果:
请输入用户名:xxx' or 1=1 -- xxxxx
请输入密码:
select * from userinfo where username=%s and password=%s;
0
用户名和密码错误!

commit方法

当我们通过pymysql来执行增删改动作的时候,需要commit以下才能生效。

sql='insert into userinfo(name,password) values(%s,%s);'
res=cursor.executemany(sql,[("root","123456"),("lhf","12356"),("eee","156")]) #执行sql语句,返回sql影响成功的行数,一次插多条记录
print(res)
#上面的几步,虽然都有返回结果,也就是那个受影响的函数res,但是你去数据库里面一看,并没有保存到数据库里面,
conn.commit() #必须执行conn.commit,注意是conn,不是cursor,执行这句提交后才发现表中插入记录成功,没有这句,上面的这几步操作其实都没有成功保存。

pymysql模块使用介绍的更多相关文章

  1. 8-5 Navicat工具与pymysql模块

    一 Navicat 在生产环境中操作MySQL数据库还是推荐使用命令行工具mysql,但在我们自己开发测试时,可以使用可视化工具Navicat,以图形界面的形式操作MySQL数据库 需要掌握的基本操作 ...

  2. MySQL -Naivacat工具与pymysql模块

    Navicat 在生产环境中操作MySQL数据库还是推荐使用命令行工具mysql,但在我们自己开发测试时,可以使用可视化工具Navicat,以图形界面的形式操作MySQL数据库. 官网下载:https ...

  3. pymysql 模块介绍

    pymysql模块是python与mysql进行交互的一个模块. pymysql模块的安装: pymysql模块的用法: import pymysql user=input('user>> ...

  4. Mysql(六):数据备份、pymysql模块

    一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https://pan.baidu.com/s/1bpo5mqj 掌握: #1. 测试+链接 ...

  5. PyMySQL模块的使用

    PyMySQL介绍 PyMySQL是在Python3.x版本中用于连接MySQL服务器的一个库,Python2系列中则使用mysqldb.Django中也可以使用PyMySQL连接MySQL数据库. ...

  6. Python连接MySQL数据库之pymysql模块使用

    安装PyMySQL pip install pymysql PyMySQL介绍 PyMySQL是在python3.x版本中用于连接MySQL服务器的一个库,2中则使用mysqldb. Django中也 ...

  7. MySQL之数据备份、pymysql模块

    一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https://pan.baidu.com/s/1bpo5mqj 掌握: #1. 测试+链接 ...

  8. 第五篇:数据备份、pymysql模块

    http://www.cnblogs.com/linhaifeng/articles/7525619.html#_label3 一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们 ...

  9. python 存储引擎 mysql(库,表, 行) 单表多表操作 (foreign key) sql_mode pymysql模块讲解

    ##################总结############### mysql 常用数据类型 整型:tinyint  int(42亿条左右)  bigint 小数:float double dec ...

随机推荐

  1. Java基础进阶:继承重点摘要,继承详解,方法重写注意事项,方法重载与重写的区别,抽象类,代码块, 附重难点,代码实现源码,课堂笔记,课后扩展及答案

    继承重点摘要 *继承的特点: 子类在初始化之前,一定要先完成父类数据的初始化 子类在初始化之前,一定要先访问父类构造,完成父类数据的初始化 系统在每一个构造方法中默认隐藏了一句super(); 如果我 ...

  2. 基于frp的内网穿透实例1-通过SSH访问内网机器

    原文地址:https://wuter.cn/1804.html/ 老母鸡终于到了,作为一个能运行linux系统的四核1G硬件,它还是比较小巧的. FRP 全名:Fast Reverse Proxy.F ...

  3. 机器学习 第4篇:数据预处理(sklearn 插补缺失值)

    由于各种原因,现实世界中的许多数据集都包含缺失值,通常把缺失值编码为空白,NaN或其他占位符.但是,此类数据集与scikit-learn估计器不兼容,这是因为scikit-learn的估计器假定数组中 ...

  4. 后台查询出来的list结果 在后台查询字典表切换 某些字段的内容

    list=listEFormat(list, "Class_type", "611");//list查询数据库得到的结果Class_type /** * @Ti ...

  5. 后台返回的json数据,前台需要修改对象的键值名,重新修改数据格式

    //例如,后台返回的数据为: var json = { data: [   {value: 103.95, name: "法拉利"}, {value: 103.2, name: & ...

  6. MM-RFQ询价报价

    (1).询价报价单事务码:ME41/ME42/ME43 需要的主数据:采购组织.供应商.采购组,物料 (2)ME47:维护供应商的报价.可以用项目明细的条件对供应商的报价进行详细设置. (3)供应商价 ...

  7. [leetcode]75.Sort Color三指针

    import java.util.Arrays; /** * Given an array with n objects colored red,white or blue, * sort them ...

  8. git 只提交部分文件 拉取pull远程仓库

    正常的团队开发中,在提交代码push之前要先pull拉取远程仓库的代码.而拉取pull操作需要先commit修改的文件才能成功. 那么问题来了,当我只想push提交部分代码的时候,同样需要pull拉取 ...

  9. LVS之1---工作原理

    LVS之1---工作原理 LVS 介绍 LVS:Linux Virtual Server,Linux虚拟服务器,负载调度器,是一个由章文嵩(花名 正明)博士从1998年开始发起的自由软件项目. 软件作 ...

  10. 设计模式之SOLID原则

    介绍 设计模式中的SOLID原则,分别是单一原则.开闭原则.里氏替换原则.接口隔离原则.依赖倒置原则.前辈们总结出来的,遵循五大原则可以使程序解决紧耦合,更加健壮. SRP 单一责任原则 OCP 开放 ...