mysql--pymysql 模块
Posted DESOLATE.X
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql--pymysql 模块相关的知识,希望对你有一定的参考价值。
一.pymysql模块
1.安装
pip3 install pymysql
2. 连接,执行slq,关闭(游标)
import pymysql conn = pymysql.connect( host=‘127.0.0.1‘,#localhost port=3306, user=‘root‘, password=‘222‘, #字符串 database=‘shanku‘, charset=‘utf8‘ ) username = input(‘请输入用户名‘) pwd = input(‘请输入密码‘) # cursor = conn.cursor() #获取元组类型数据的游标 cursor = conn.cursor(pymysql.cursors.DictCursor) #获取字典类型数据的游标 # sql = ‘show databases;‘ # sql = ‘select * from student;‘ sql = ‘select * from student;‘ # sql = "select * from userinfo where username=‘%s‘ and password=‘%s‘;"%(username,pwd) res = cursor.execute(sql) #res受影响的行 # print(cursor.fetchall()) print(cursor.fetchone()) # cursor.scroll(2,‘absolute‘) cursor.scroll(1,‘relative‘) print(‘>>>>>‘,cursor.fetchone()) # print(‘>>>>>‘,cursor.fetchmany(1)) # print(res)
3.使用commit()
import pymysql conn = pymysql.connect( host=‘127.0.0.1‘,#localhost port=3306, user=‘root‘, password=‘222‘, #字符串 database=‘db1‘, charset=‘utf8‘ ) cursor = conn.cursor(pymysql.cursors.DictCursor) #获取字典类型数据的游标 sql = "insert into userinfo values(4,‘gaowang‘,666);" res = cursor.execute(sql) #res受影响的行 print(res) conn.commit() #凡是增删改的操作都需要commit
4.游标的移动
#我们可以再创建游标的时候,在cursor里面加上一个参数:cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)获取的结果就是字典格式的,fetchall或者fetchmany取出的结果是列表套字典的数据形式
这个取数据的操作就像读取文件内容一样,每次read之后,光标就移动到了对应的位置,我们可以通过seek来移动光标 同样,我们可以移动游标的位置,继续取我们前面的数据,通过cursor.scroll(数字,模式),第一个参数就是一个int类型的数字,表示往后移动的记录条数,第二个参数为移动的模式,有两个值:absolute:绝对移动,relative:相对移动 #绝对移动:它是相对于所有数据的起始位置开始往后面移动的 #相对移动:他是相对于游标的当前位置开始往后移动的 #绝对移动的演示 #print(cursor.fetchall()) #cursor.scroll(3,‘absolute‘) #从初始位置往后移动三条,那么下次取出的数据为第四条数据 #print(cursor.fetchone()) #相对移动的演示 #print(cursor.fetchone()) #cursor.scroll(1,‘relative‘) #通过上面取了一次数据,游标的位置在第二条的开头,我现在相对移动了1个记录,那么下次再取,取出的是第三条,我相对于上一条,往下移动了一条 #print(cursor.fetchone())
二.execute()之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(‘用户名和密码错误!‘) #通过上面的验证方式,比我们使用文件来保存用户名和密码信息的来进行验证操作要方便很多。
我们来看一个,直接连,不用知道用户名和密码,依然可以成功登陆的例子.如果在登陆时这样输入
第一种输入方式:
asd‘ -- xx
这样输入的话等同于
select * from userinfo where username=‘asd‘ -- xxx‘ and password=‘‘;
第二种输入方式:
请输入用户名:xxx‘ or 1=1 -- xxxxxx 请输入密码: select * from userinfo where username=‘xxx‘ or 1=1 -- xxxxxx‘ and password=‘‘; 登陆成功 我们只输入了一个xxx‘ 加or 加 1=1 加 -- 加任意字符串 看上面被执行的sql语句你就发现了,or 后面跟了一个永远为真的条件,那么即便是username对不上,但是or后面的条件是成立的,也能够登陆成功。
总结咱们刚才说的两种sql注入的语句
#1、sql注入之:用户存在,绕过密码 asd‘ -- 任意字符 #2、sql注入之:用户不存在,绕过用户与密码 xxx‘ or 1=1 -- 任意字符
为了解决这个问题,pymysql提供了excute()方法来帮我们拼接,并防止mysql注入
# 原来是我们对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的规矩来。
示例:
import pymysql conn = pymysql.connect( host=‘127.0.0.1‘,#localhost port=3306, user=‘root‘, password=‘222‘, #字符串 database=‘shanku‘, charset=‘utf8‘ ) username = input(‘请输入用户名‘) pwd = input(‘请输入密码‘) # cursor = conn.cursor() #获取元组类型数据的游标 cursor = conn.cursor(pymysql.cursors.DictCursor) #获取字典类型数据的游标 # sql = "select * from userinfo where username=‘%s‘ and password=‘%s‘;"%(username,pwd) sql = "select * from userinfo where username=%s and password=%s;" print(‘>>>>>‘,sql) res = cursor.execute(sql,[username,pwd]) #res受影响的行 print(res) if res: print(‘登录成功‘) else: print(‘登录失败‘) # conn.commit()
三.增、删、改:conn.commit()
import pymysql #链接 conn=pymysql.connect(host=‘localhost‘,port=‘3306‘,user=‘root‘,password=‘123‘,database=‘crm‘,charset=‘utf8‘) #游标 cursor=conn.cursor() #执行sql语句 #part1 # sql=‘insert into userinfo(name,password) values("root","123456");‘ # res=cursor.execute(sql) #执行sql语句,返回sql影响成功的行数 # print(res) # print(cursor.lastrowid) #返回的是你插入的这条记录是到了第几条了 #part2 # sql=‘insert into userinfo(name,password) values(%s,%s);‘ # res=cursor.execute(sql,("root","123456")) #执行sql语句,返回sql影响成功的行数 # print(res) #还可以进行更改操作: #res=cursor.excute("update userinfo set username=‘taibaisb‘ where id=2") #print(res) #结果为1 #part3 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,执行这句提交后才发现表中插入记录成功,没有这句,上面的这几步操作其实都没有成功保存。 cursor.close() conn.close()
四 查:fetchone,fetchmany,fetchall
import pymysql #链接 conn=pymysql.connect(host=‘localhost‘,user=‘root‘,password=‘123‘,database=‘egon‘) #游标 cursor=conn.cursor() #执行sql语句 sql=‘select * from userinfo;‘ rows=cursor.execute(sql) #执行sql语句,返回sql影响成功的行数rows,将结果放入一个集合,等待被查询 # cursor.scroll(3,mode=‘absolute‘) # 相对绝对位置移动 # cursor.scroll(3,mode=‘relative‘) # 相对当前位置移动 res1=cursor.fetchone() res2=cursor.fetchone() res3=cursor.fetchone() res4=cursor.fetchmany(2) res5=cursor.fetchall() print(res1) print(res2) print(res3) print(res4) print(res5) print(‘%s rows in set (0.00 sec)‘ %rows) conn.commit() #提交后才发现表中插入记录成功 cursor.close() conn.close()
五 获取插入的最后一条数据的自增ID
mport pymysql conn=pymysql.connect(host=‘localhost‘,user=‘root‘,password=‘123‘,database=‘egon‘) cursor=conn.cursor() sql=‘insert into userinfo(name,password) values("xxx","123");‘ rows=cursor.execute(sql) print(cursor.lastrowid) #在插入语句后查看 conn.commit() cursor.close() conn.close()
以上是关于mysql--pymysql 模块的主要内容,如果未能解决你的问题,请参考以下文章
MySQL— pymysql模块(防止sql注入),可视化软件Navicat
48-mysql-Navicat数据库查询题目讲解(多表操作)python操作MySQLsql注入问题pymysql模块增删改查数据操作