本节重点:python
以前咱们都是经过MySQL自带的命令行客户端工具mysql来操做数据库,那如何在python程序中操做数据库呢?这就用到了pymysql模块,该模块本质就是一个套接字客户端软件,使用前须要事先安装。mysql
pip3 install pymysql
实现:使用Python实现用户登陆,若是用户存在则登陆成功(假设该用户已在数据库中)sql
import pymysql user = input('请输入用户名:').strip() pwd = input('请输入密码:').strip() # 1.链接 #建立一个链接对象<pymysql.connections.Connection object at 0x005F2910> conn = pymysql.connect(host='192.168.76.136', port=3306, user='root', password='root', db='db1', charset='utf8') # 2.建立游标 #建立一个游标对象<pymysql.cursors.Cursor object at 0x005E0290> cursor = conn.cursor() #注意%s须要加引号 sql = 'select * from user where username="%s" and password="%s"'%(user, pwd) print(sql) # 3.执行sql语句 result = cursor.execute(sql) #执行sql语句,返回sql查询成功的记录数目,不是查询内容 print(result) # 4.关闭链接,游标和链接都要关闭 cursor.close() conn.close() #打印结果时能够根据判断输出不一样结果 if result: print('登录成功') else: print('登陆失败') 或 print('登陆成功') if res else print('登陆失败')
最后那一个空格,在一条sql语句中若是遇到select * from userinfo where username='user1' -- asadasdas' and pwd='' 则--以后的条件被注释掉了(注意--后面还有一个空格)数据库
#一、sql注入之:用户存在,绕过密码
user1' -- 任意字符工具
#二、sql注入之:用户不存在,绕过用户与密码
xxx' or 1=1 -- 任意字符
fetch
解决方法: spa
# 原来是咱们对sql进行字符串拼接 # sql="select * from userinfo where name='%s' and password='%s'" %(username,pwd) # print(sql) # result=cursor.execute(sql) #改写为(execute帮咱们作字符串拼接,咱们无需且必定不能再为%s加引号了) sql="select * from userinfo where name=%s and password=%s" #!!!注意%s须要去掉引号,由于pymysql会自动为咱们加上 result=cursor.execute(sql,[user,pwd]) #pymysql模块自动帮咱们解决sql注入的问题,只要咱们按照pymysql的规矩来。 sql = 'select * from user where username=%s and password=%s' res = cursor.execute(sql, (user, pwd))
commit()方法:在数据库里增、删、改的时候,必需要进行提交,不然插入的数据不生效。命令行
import pymysql user = input('请输入用户名:').strip() pwd = input('请输入密码:').strip() conn = pymysql.connect(host='192.168.76.136', port=3306, user='root', password='root', db='db1', charset='utf8') cursor = conn.cursor()
#定义insert语句指针
sql_insert = 'insert into user (username, password) values (%s, %s)' res = cursor.execute(sql_insert, (user, pwd)) #必定要commit conn.commit() cursor.close() conn.close() print('登陆成功') if res else print('登陆失败') mysql> select * from user; +----+----------+----------+----------------+ | id | username | password | emall | +----+----------+----------+----------------+ | 1 | user1 | 123 | user1@test.com | | 2 | user2 | 123 | user2@test.com | | 3 | user3 | 123 | NULL | +----+----------+----------+----------------+
#添加多条记录,参数是一个列表中的多个集合code
res = cursor.executemany(sql_insert, [('aaa',123),('bbb',123)]) conn.commit() cursor.close() conn.close() mysql> select * from user; +----+----------+----------+----------------+ | id | username | password | emall | +----+----------+----------+----------------+ | 1 | user1 | 123 | user1@test.com | | 2 | user2 | 123 | user2@test.com | | 3 | user3 | 123 | NULL | | 4 | aaa | 123 | NULL | | 5 | bbb | 123 | NULL | +----+----------+----------+----------------+
#定义修改update语句
sql_update = 'update user set username = %s where id=2' res = cursor.execute(sql_update, user) conn.commit() cursor.close() conn.close() mysql> select * from user; +----+----------+----------+----------------+ | id | username | password | emall | +----+----------+----------+----------------+ | 1 | user1 | 123 | user1@test.com | | 2 | test1 | 123 | user2@test.com | | 3 | user3 | 123 | NULL | | 4 | aaa | 123 | NULL | | 5 | bbb | 123 | NULL | +----+----------+----------+----------------+
#定义删除delete语句
sql_delete = 'delete from user where id=4' res = cursor.execute(sql_delete) conn.commit() cursor.close() conn.close() mysql> select * from user; +----+----------+----------+----------------+ | id | username | password | emall | +----+----------+----------+----------------+ | 1 | user1 | 123 | user1@test.com | | 2 | test1 | 123 | user2@test.com | | 3 | user3 | 123 | NULL | | 5 | bbb | 123 | NULL | +----+----------+----------+----------------+
fetchone():获取下一行数据,第一次为首行,可屡次执行。
fetchall():获取全部行数据源
fetchmany(4):获取4行数据,n可指定
查看表内容:
一、fetchone()
import pymysql conn = pymysql.connect(host='192.168.76.136', port=3306, user='root', password='root', db='db1', charset='utf8') cursor = conn.cursor() #定义查询语句 sql_select = 'select * from user ' res = cursor.execute(sql_select) row = cursor.fetchone() print(row) row = cursor.fetchone() print(row) cursor.close() conn.close() 结果:每执行一次查询一行,可屡次执行逐行查看 (1, 'user1', 123, 'user1@test.com') (2, 'test1', 123, 'user2@test.com')
二、fetchmany(n)
row = cursor.fetchmany(3) print(row) 结果:显示3条记录 ((1, 'user1', 123, 'user1@test.com'), (2, 'test1', 123, 'user2@test.com'), (3, 'user3', 123, None))
三、cursor.fetchall()
row = cursor.fetchall() print(row) 结果:显示全部记录 ((1, 'user1', 123, 'user1@test.com'), (2, 'test1', 123, 'user2@test.com'), (3, 'user3', 123, None), (5, 'bbb', 123, None))
四、DictCursor
默认状况下,咱们获取到的返回值是元组,在获取数据的时候并不方便,可使用如下方式来返回字典,每一行的数据都会生成一个字典: #在实例化conn的时候,将属性cursor设置为pymysql.cursors.DictCursor cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) 结果: [{'id': 1, 'username': 'user1', 'password': 123, 'emall': 'user1@test.com'}, {'id': 2, 'username': 'test1', 'password': 123, 'emall': 'user2@test.com'}, {'id': 3, 'username': 'user3', 'password': 123, 'emall': None}, {'id': 5, 'username': 'bbb', 'password': 123, 'emall': None}]
五、指针位置移动
在fetchone示例中,在获取行数据的时候,能够理解开始的时候,有一个行指针指着第一行的上方,获取一行,它就向下移动一行,因此当行指针到最后一行的时候,就不能再获取到行的内容,因此咱们可使用以下方法来移动行指针: cursor.scroll(1,mode='relative') # 相对当前位置移动 cursor.scroll(2,mode='absolute') # 相对绝对位置移动 第一个值为移动的行数,整数为向下移动,负数为向上移动,mode指定了是相对当前位置移动,仍是相对于首行移动 sql = 'select * from user' cursor.execute(sql) # 查询第一行的数据 row = cursor.fetchone() print(row) # 查询第二行数据 row = cursor.fetchone() print(row) cursor.scroll(-1,mode='relative') #设置以后,光标相对于当前位置(第3行)往前移动了一行,因此打印的结果为第二行的数据 row = cursor.fetchone() print(row) cursor.scroll(0,mode='absolute') #设置以后,光标相对于首行没有任何变化,因此打印的结果为第一行数据 row = cursor.fetchone() print(row)