pymysql是一个socket客户端,使用它需要先建立连接
基本使用
- 连接数据库
import pymysql
conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '',
database = 'db1',
charset = 'utf8',
)
- 获取游标
cursor = conn.cursor()
cursor = conn.cursor(pymysql.cursors.DictCursor)
# 获取游标时,通常用此方法获取,这样查询返回的数据是字典的形式,
1. key是字段,value是字段值
2. 每个字典就是一条记录
- 向游标提交sql语句
rows = cursor.execute('show tables;')
print(rows) # 2 得到的结果是响应的行数
补充: 当输入的sql语句的查询没有结果时,影响行数为0
我们在cmd里执行sql语句得到的是数据结果和行数,在python中执行的sql语句打印出来的只有行数,实际上数据结果也拿到了,此时在内存中,可以继续通过游标获取
- 获取数据
获取一条 : fetchone()
获取所有 : fetchall()
获取指定数量: fetchmany(size)
rows = cursor.execute('select * from dep')
print(rows) # 4
print(cursor.fetchone())
# {'id': 200, 'name': '技术'}
print(cursor.fetchmany(2))
# [{'id': 200, 'name': '技术'}, {'id': 201, 'name': '人力资源'}]
print(cursor.fetchall())
# [{'id':200, 'name': '技术'},{'id': 201, 'name': '人力资源'}, {'id': 202, 'name': '销售'}, {'id': 203, 'name': '运营'}]
- 关闭游标关闭socket连接通道
cursor.close()
conn.close()
标控制
- absolute 绝对移动
cursor.scroll(2, 'absolute') # 相对于起始位置移动2位
print(cursor.fetchone()) # {'id': 202, 'name': '销售'}
- relative 相对移动
cursor.scroll(3,'relative') # 相对当前光标所在位置移动3位
print(cursor.fetchone()) # {'id': 203, 'name': '运营'}
sql注入问题
案例表
# 创建user表
create table user(
id int primary key auto_increment,
name char(16) not null unique,
password char(16) not null
);
# 插入数据
insert into user(id, name, password) values(1, 'xiongda', 123), (2, 'xionger', 456)
# select * from user;
+----+---------+----------+
| id | name | password |
+----+---------+----------+
| 1 | xiongda | 123 |
| 2 | xionger | 456 |
+----+---------+----------+
sql注入是利用sql的注释,or 等一些特殊字符,来改变sql的执行逻辑,从而使sql语句正常执行,得到数据.
cursor = conn.cursor(pymysql.cursors.DictCursor)
username = input(">>>:").strip()
password = input(">>>:").strip()
sql = "select * from user where name = '%s' and password = '%s'" %(username, password)
rows = cursor.execute(sql)
if rows:
print('登录成功')
else:
print('登录失败')
cursor.close()
conn.close()
>>>:xiongda' -- 1564as3d13a1sd
>>>:
登录成功
>>>:xiongda' or 1=1 -- 1as32d13a2s1d
>>>:
登录成功
解决方法
原来我是自己对sql语句进行字符串拼接,导致sql注入问题
改写为利用execute帮助我们字符串拼接,pymysql帮我们处理了特殊符号
sql = "select * from user where name = %s and password = %s"
rows = cursor.execute(sql, [username, password])
增、删、改:conn.commit()
增删改对于数据库来说都是敏感操作,提交完sql语句后都要加上conn.commit(),才能真正的对数据增删改
sql = "insert into user (name, password) values(%s, %s)"
rows = cursor.execute(sql, ['xxx', 789])
rows = cursor.executemany(sql, [('yyy',111), ('www', 321)]) # 一次插入多条数据
print(cursor.lastrowid) # 当前记录是第几条
conn.commit()
也可以在连接数据库时配置autocommit = True,就不需要手动写conn.commit()
conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '',
database = 'db1',
charset = 'utf8',
autocommit = True # 这个参数配置后,增删改操作都不会需要手动加conn.commit了
)