day36
pymsql 模块
1. pymsql的使用
import pymysql # 导入 pymysql 模块
# 连接数据库
conn = pymysql.connect(host = 'IP', user = '用户名', password = '密码', database = '数据库名称', charset = 'utf8')
# 游标
cursor = conn.cursor() # 执行完毕后返回的结果默认以元祖的形式展示
# cursor = conn.cursor(cursor = pymysql.cursors.DictCursor) # 执行完毕后返回的结果以字典的形式展示,推荐使用
# 执行 SQL 指令
sql = 'SQL指令' # 如果需要传入参数,在指令里面使用占位符,在下面的 cursor.execute(sql) 函数中,将参数按顺序写在 sql 后面
res = cursor.execute(sql,(参数...)) # 执行 SQL指令,返回查询成功的记录
conn.commit() # 如果对数据库里的数据做改动,必须加这一行
# 断开数据库的连接
cursor.close()
conn.close()
1.1 增
import pymysql # 导入 pymysql 模块
# 连接数据库
conn = pymysql.connect(host = 'IP', user = '用户名', password = '密码', database = '数据库名称', charset = 'utf8')
# 游标
# cursor = conn.cursor() # 执行完毕后返回的结果默认以元祖的形式展示
cursor = conn.cursor(cursor = pymysql.cursors.DictCursor) # 执行完毕后返回的结果以字典的形式展示
'''
1.增加一条数据
# 执行 SQL 指令
sql = 'insert into user (name,password) values (%s, %s)' # 添加数据的 SQL指令
res = cursor.execute(sql,('tom','123')) # 将 SQL指令和数据发给 mysql,执行后拿到结果
conn.commit() # 提交
2.增加多条数据
# 准备要添加的数据
data = [
('name1','password1'),
('name1','password1'),
('name1','password1')
]
sql = 'insert into user (name,password) values (%s, %s)' # 添加数据的 SQL指令
res = executemany(sql, data) # 将 SQL指令和数据发给 mysql,执行后拿到结果
conn.commit()
'''
# 断开数据库的连接
cursor.close()
conn.close()
1.2 改
import pymysql # 导入 pymysql 模块
# 连接数据库
conn = pymysql.connect(host = 'IP', user = '用户名', password = '密码', database = '数据库名称', charset = 'utf8')
# 游标
# cursor = conn.cursor() # 执行完毕后返回的结果默认以元祖的形式展示
cursor = conn.cursor(cursor = pymysql.cursors.DictCursor) # 执行完毕后返回的结果以字典的形式展示
# 执行 SQL 指令
sql = 'update user set name=%s where id=%s' # 修改数据的 SQL指令
res = cursor.execute(sql,('jack',2)) # 将 SQL指令和数据发给 mysql,执行后拿到结果
conn.commit() # 如果对数据库里的数据做改动,必须加这一行
# 断开数据库的连接
cursor.close()
conn.close()
1.3 删
import pymysql # 导入 pymysql 模块
# 连接数据库
conn = pymysql.connect(host = 'IP', user = '用户名', password = '密码', database = '数据库名称', charset = 'utf8')
# 游标
# cursor = conn.cursor() # 执行完毕后返回的结果默认以元祖的形式展示
cursor = conn.cursor(cursor = pymysql.cursors.DictCursor) # 执行完毕后返回的结果以字典的形式展示
# 执行 SQL 指令
sql = 'delete from t3 where id=%s' # 删除数据的 SQL指令
res = cursor.execute(sql,(1,)) # 将 SQL指令和数据发给 mysql,执行后拿到结果
conn.commit() # 如果对数据库里的数据做改动,必须加这一行
# 断开数据库的连接
cursor.close()
conn.close()
1.4 查
import pymysql # 导入 pymysql 模块
# 连接数据库
conn = pymysql.connect(host = 'IP', user = '用户名', password = '密码', database = '数据库名称', charset = 'utf8')
# 游标
# cursor = conn.cursor() # 执行完毕后返回的结果默认以元祖的形式展示
cursor = conn.cursor(cursor = pymysql.cursors.DictCursor) # 执行完毕后返回的结果以字典的形式展示
# 执行 SQL 指令
sql = 'delete from t3 where id=%s' # 查询数据的 SQL指令
cursor.execute(sql,(1,)) # 将 SQL指令和数据发给 mysql,执行后拿到结果
res = cursor.fetchone() # 取出查询结果的一条数据,字典
res = cursor.fetchall() # 取出查询结果的所有数据,列表套字典
res = cursor.fetchmany(size) # 指定取出查询结果的数量,列表套字典
print(res) # 打印查询结果
# 断开数据库的连接
cursor.close()
conn.close()
2. pymysql的注入攻击
为什么在编写 SQL指令时,参数需要使用 execute()
函数传入,而不是直接在 SQL指令里面构造好,就是为了防止 SQL注入攻击。
2.1 原理
通过构建特殊的输入值作为参数,从而完成欺骗 MySQL ,进而执行恶意的 SQL指令。
如果将 SQL指令写成如下形式:
sql = "select * from user where name='%s' and password='%s'" % (user, pwd) # (user,pwd)由用户输入
我们将 user 和 pwd 输入“admin' or '1” 我们就能意外的进入到登录页面之后了
当用户输入
select * from [users] where username= 'admin' or '1' and password='admin' or '1'
根据SQL中逻辑运算的优先级,or低于and,最后的or ‘1’永远成立,所以该条件表达式结果为True,
此语句同等于select * from [users]
2.2 防范的方法
- 不要相信用户的输入,对用户输入的信息做校验,比如特殊字符等...
- 使用 pymsql 提供的
execute()
函数传入用户输入的参数,这个函数会自动对用户输入的信息进行校验 - 对重要数据进行加密处理