数据库pymysql下的查询操作以及SQL注射

93 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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';
  1. 我们可以采用SQL注射的方法直接免密码登录
  • 比如:我们在密码栏直接输入x' or '1' = '1这样一来我们的查询语句就会变成这样
select * from tb_user where username='admin' and password='x' or '1' = '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';

因此我们千万不要用这种方式来写查询结构