持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天
pymysql下的查询
import pymysql
def add():
conn = pymysql.connect(host='主机IP址',port=3306,user='',password='',db='数据库名称',charset='utf8')
try:
with conn.cursor() as cursor:
cursor.execute('select dno,dname,dloc from tb_dept')
for row in cursor.fetchall():
print(f'部门编号:{row[0]}')
print(f'部门名称:{row[1]}')
print(f'部门所在地:{row[2]}')
except pymysql.MySQLError as error:
print(error)
finally:
conn.close()
- 注意这里的fetchall()返回的是一个大元组
- fetchall(游标)如果先拿走了一行则下面的fetchall只能拿到剩下的
- 如果我们想用字典,不用元组,我们可以改一下游标类型
conn = pymysql.connect(cursorclass = pymysql.cursors.DictCursor)
#只要在连接的时候在里面加一行cursorclass = pymysql.cursors.DictCursor即可将元组游标改成字典游标
- 我们来用面向对象的方法解决打印输出结果的问题
#我们来看一下具体解决方法
#原始写法(这是基于字典型游标)
with conn.cursor() as cursor:
cursor.execute('select dno as no,dname as name,dloc as location from tb_dept')
for row in cursor.fetchall():
print(row['no'],end='\t')
print(row['name'],end='\t')
print(['location'],end='\t')
#面向对象写法
class Dept(object):
def __int__(self,no,name,location):
self.no=no
self.name=name
self.location=location
def __str__(self):
return f'{self.no}\t{self.name}\t{self.location}'
with conn.cursor() as cursor:
cursor.execute('select dno as no,dname as name,dloc as location from tb_dept')
for row in cursor.fetchall():
for row in cursor.fetchall():
dept = Dept(**row)
print(dept)
- 我们只需要定义一个对象让后对对for循环内部的语句进行改动于是我们就有了上面两种相同的效果代码
SQL注射攻击
千万不能用字符串拼接
- 例如这是一张表 (tb_user)
id name password
1 admin 123456
- 这里是我们拿到用户输入密码的语句(用格式化写的)
select * from tb_user where username='%s' and password='%s';
- 我们可以采用SQL注射的方法直接免密码登录
- 比如:我们在密码栏直接输入x' or '1' = '1这样一来我们的查询语句就会变成这样
select * from tb_user where username='admin' and password='x' or '1' = '1';
这样我们就能使后面的密码恒成立
- 我们还可以采用SQL注射的方法直接更新数据库甚至删除数据库
- 比如:我们在密码栏输入'; update (drop)... where '1' = '1
select * from tb_user where username='admin' and password='x' or '1' = '1';
update(drop) ... where '1' = '1';
因此我们千万不要用这种方式来写查询结构