pymysql模块

支持python代码操作数据库MySQL

#安装, 不用考虑版本
pip3 install pymysql

1  链接、执行sql、关闭(游标)

 

import pymysql
user=input('用户名: ').strip()
pwd=input('密码: ').strip()

#链接
conn=pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    password='123',
    database='db_test',
    charset='utf8')

#生成一个游标对象,类似终端的光标,等待输入sql命令
cursor=conn.cursor()                                  #执行完毕返回的结果集默认以元组显示,无法区分数据的含义
cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) #加入参数,表示将查询结果以字典的形式返回

#执行sql语句
sql='select * from userinfo where name="%s" and password="%s"' %(user,pwd) #注意%s需要加引号
print(sql)
res=cursor.execute(sql) #执行sql语句,execute返回的是你当前sql语句所影响/作用的行数,表示命令执行成功,该返回值一般不用
print(res)

cursor.close()
conn.close()

if res:
    print('登录成功')
else:
    print('登录失败')

 

2 execute()之sql注入 

什么是sql注入?

利用一些语法的特性,书写一些特定的语句实现固定的语法,sql注入有很多种形式,注释语法是最有代表性的,MySQL利用的是MySQL的注释语法。

日常生活中很多软件在注册的时候都不能含有特殊符号,因为怕你构造出特定的语句入侵数据库,不安全。

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

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

最后那一个空格,在一条sql语句中如果遇到select * from t1 where id > 3 -- and name='egon';  则--之后的条件被注释掉了

在上例中,输入用户名与密码时,sql语句是自己拼接的,如果书写如下特定语句,在MySQL中会识别为注释语法
#1、sql注入之:用户存在,绕过密码
egon' -- 任意字符 
select * from user where name ='egon' --abcdefg and password=''  #--相当于把后面的语句注释了,因此不输密码也能登录


#2、sql注入之:用户不存在,绕过用户与密码
xxx' or 1=1 -- 任意字符
select *from user where name = 'xxx' or 1=1 --abcdefg and password =''  #1=1成立,修改了name的条件,密码注释掉了,没有用户名和密码也能登录

解决方法:

敏感的数据不要自己做拼接操作,交由固定模块帮你去过滤数据,防止sql注入,pymysql中利用的是execute

# 原来是我们对sql进行字符串拼接
sql="select * from userinfo where name='%s' and password='%s'" %(user,pwd)
print(sql)
res=cursor.execute(sql)

#改写为(execute帮我们做字符串拼接,我们无需且一定不能再为%s加引号了)
#不要手动拼接数据,先用%s占位,之后将需要拼接的数据直接交给execute方法即可,注意:只能识别%s
sql="select * from userinfo where name=%s and password=%s"   #注意%s需要去掉引号,因为pymysql会自动为我们加上
res=cursor.execute(sql,(user,pwd))  #自动识别sql里面的%s用后面元组里面的数据替换

 

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

查不涉及数据修改,增删改的操作涉及到数据修改,因此在输入命令后不能直接执行,需要二次确认

3.1 insert

import pymysql
#链接
conn=pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    password='123',
    database='db_test',
    autocommit=True) #commit改为自动提交
#游标
cursor=conn.cursor()

#执行sql语句
#part1
sql='insert into userinfo(name,password) values("root","123456");'
res=cursor.execute(sql) #执行sql语句,返回sql影响成功的行数
print(res)

#part2 
sql='insert into userinfo(name,password) values(%s,%s);'
res=cursor.execute(sql,("root","123456")) #执行sql语句,返回sql影响成功的行数
print(res)

#part3  一次性增加多条数据,列表套元祖的格式
sql='insert into userinfo(name,password) values(%s,%s);'
res=cursor.executemany(sql,[("root","123456"),("lhf","12356"),("eee","156")]) #执行sql语句,返回sql影响成功的行数
print(res)

conn.commit()  #提交后才发现表中插入记录成功
cursor.close()
conn.close()

3.2 delete

import pymysql
#链接
conn=pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    password='123',
    database='db_test',
    autocommit=True) #commit改为自动提交
#游标
cursor=conn.cursor()

#执行sql语句
sql='delete from user where id=1'
rows=cursor.execute(sql)  #执行sql语句,返回sql影响成功的行数
print(rows)

conn.commit()  #提交后才发现表中插入记录成功
cursor.close()
conn.close()

3.3 update

import pymysql
#链接
conn=pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    password='123',
    database='db_test',
    autocommit=True) #commit改为自动提交
#游标
cursor=conn.cursor()

#执行sql语句
sql='update user set name='egon_sb' where id=1'
rows=cursor.execute(sql)  #执行sql语句,返回sql影响成功的行数
print(rows)

conn.commit()  #提交后才发现表中插入记录成功
cursor.close()
conn.close()

 

4 查:fetchone,fetchmany,fetchall

import pymysql
#链接
conn=pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    password='123',
    database='db_test')
#游标
cursor=conn.cursor()

#执行sql语句
sql='select * from userinfo;'
rows=cursor.execute(sql)  #执行sql语句,返回sql影响成功的行数rows, 将结果放入一个集合等待被查询

#获取命令的执行结果
#读取数据类似文件光标的移动,同时执行五条命令,每取一条数据,光标就往后移动
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)

cursor.close()
conn.close()

'''
(1, 'root', '123456')
(2, 'root', '123456')
(3, 'root', '123456')
((4, 'root', '123456'), (5, 'root', '123456'))
((6, 'root', '123456'), (7, 'lhf', '12356'), (8, 'eee', '156'))
rows in set (0.00 sec)
'''

控制光标移动的两种方式

# cursor.scroll(3,mode='absolute') # 相对绝对位置移动,相对于数据的开头(0个数据的位置),往后移动三位
# cursor.scroll(3,mode='relative') # 相对当前位置移动,相对于当前位置往后移动三位

 

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

import pymysql
conn=pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    password='123',
    database='db_test')

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()

 

posted @ 2022-12-14 02:57  不会钓鱼的猫  阅读(109)  评论(0编辑  收藏  举报