Python + pymysql 之 MySQL 查询操作
在MySQL中构建一个测试表,如下:
查询单条数据
# -*- coding: UTF-8 -*-import pymysqldef mysql_query(): """ MySQL查询 :return: """ # 打开数据库连接 db = pymysql.connect(host="127.0.0.1", user="root", password="testtest", database="testdb") # 使用 cursor() 方法创建一个游标对象 cursor cursor = db.cursor() # SQL语句 sql = """ select * from student_info; """ # 使用 execute() 方法执行 SQL 查询 cursor.execute(sql) # 获取第一条结果 student = cursor.fetchone() print(type(student)) print(student) # 关闭数据库连接 db.close() # 返回查询结果 return studentif __name__ == '__main__': mysql_query()
打印输出结果:
(1, '张三', '2233445566', 18)
从中可以看出,默认情况下,查询结果返回的是元组tuple形式
返回元组会有一个问题,当你只查询一个属性字段时,返回的结果会是有逗号的元组
例如:sql改变一下
sql = """ select name from student_info where id =2; """
此时,打印输出结果:
('李四',)
此时,建议return前,简单处理一下,我们只取返回结果元组的第一个元素
student = cursor.fetchone()[0]
此时,打印输出结果:
李四
这样一来,函数的输出结果就可以直接使用啦
那么,还有没有其他返回形式呢,答案是有的
还可以返回字典形式,在代码中创建游标时,传入参数,指定返回字典形式
cursor = db.cursor(pymysql.cursors.DictCursor)
此时,打印输出结果:
{'name': '李四'}
查询全部数据
把其中的
student = cursor.fetchone()
替换为
students = cursor.fetchall()
此时返回全部数据,默认为元组形式
((1, '张三', '2233445566', 18), (2, '李四', '12341234', 19), (3, '王五', '11112222', 20))
同样需要注意,如果只是查询一个属性字段的话,返回的是元组形式
(('张三',), ('李四',), ('王五',))
此时,可以用一个循环,来提取属性内容到
names = [student[0] for student in students]
此时,打印names结果为:
['张三', '李四', '王五']
传参查询
例如:根据学生id查询学生姓名
传参的方式:
# SQL语句sql = """select name from student_info where id = %s;"""# 使用 execute() 方法执行 SQL 查询cursor.execute(sql, [id])
注意:此处的占位符是%s,无论是字符串、数字或者其他类型,都是这个占位符。 %s不能加引号。
上代码
def get_name_by_id(id): """ 根据学生id查询学生姓名 :param id: :return: """ # 打开数据库连接 db = pymysql.connect(host="127.0.0.1", user="root", password="testtest", database="testdb") # 使用 cursor() 方法创建一个游标对象 cursor 以元组形式返回 cursor = db.cursor() # SQL语句 sql = """ select name from student_info where id = %s; """ # 使用 execute() 方法执行 SQL 查询 cursor.execute(sql, [id]) # 获取第一条结果 name = cursor.fetchone()[0] # 关闭数据库连接 db.close() # 返回查询结果 return nameif __name__ == '__main__': id = 3 name = get_name_by_id(id) print(name)
返回打印结果:
王五
为什么不用拼接字符串的方式来组装sql语句呢?
为了防注入,建议大家养成习惯
拿一个典型的登录注入来举例:
username = 'zhangsan' password = '123456' sql = "SELECT user_id FROM users WHERE username = '{}' AND password = '{}';".format(username, password)
看起来也没毛病,但是如果此时,username传入的是如下内容:
username = 'zhangsan OR 1 = 1 -- a'
sql就会变成这个样子了:
SELECT user_id FROM users WHERE username = 'zhangsan OR 1 = 1 -- a' AND password = '123456';
美化一下SQL
SELECTuser_id FROMusers WHEREusername = 'zhangsan' OR 1 = 1 -- a AND password = 'abc';
这段sql的效果是无论输入什么密码,都会返回登录成功。
改成使用pymysql列表方式传参就不怕注入啦
def get_user_id(username, password): # 打开数据库连接 db = pymysql.connect(host="127.0.0.1", user="root", password="testtest", database="testdb") # 使用 cursor() 方法创建一个游标对象 cursor 以元组形式返回 cursor = db.cursor() # SQL语句 sql = """ SELECT user_id FROM users WHERE username = %s AND password = %s; """ # 使用 execute() 方法执行 SQL 查询 cursor.execute(sql, [username, password]) # 获取第一条结果 user_id = cursor.fetchone() # 关闭数据库连接 db.close() # 返回查询结果 return user_idif __name__ == '__main__': username = 'zhangsan OR 1 = 1 -- a' password = 'abc' user_id = get_user_id(username, password) print(bool(user_id))
返回打印结果为:
False
来源地址:https://blog.csdn.net/light2081/article/details/131623364
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341