前言
系列文章目录
视频及资料和课件
链接:https://pan.baidu.com/s/1LCv_qyWslwB-MYw56fjbDg?pwd=1234
提取码:1234
1. 安装与卸载pymysql第三方包
1.1 安装pymysql第三方包
pip install pymysql
1.2 卸载pymysql第三方包
pip uninstall pymysql
1.3 查看已经安装的第三方包
pip list
1.4 查看指定的已经安装的第三方包的信息
pip show pymysql
2. pymysql的使用
2.1 导入 pymysql 包
import pymysql
2.2 使用 Python 操作数据库的步骤
- 创建连接数据库的连接对象
- 通过连接对象获取执行sql语句的游标对象
- 根据任务需求组织sql语句
- 使用游标对象执行sql语句(如果是对数据库进行增加、删除、修改,如果成功需要进行事务的提交,失败需要进行事务的回滚;如果是对数据库进行查询操作,可以通过游标对象获取查询的结果)
- 关闭游标
- 关闭与数据库的连接
2.3 创建连接数据库的连接对象
调用pymysql模块中的connect()
函数来创建连接对象.
conn = pymysql.connect(参数列表) # 参数说明: # host:连接的mysql主机的ip地址,如果本机是'localhost' # port:连接的mysql主机的端口,默认是3306 # user:连接的用户名 # password:连接的密码 # database:数据库的名称 # charset:通信采用的编码方式,推荐使用utf8
2.4 提交事物
连接对象.commit()
表示将修改操作提交到数据库。
2.5 回滚事物
连接对象.rollback()
如果对数据库的修改操作失败,调用该函数,表示回滚数据,撤销对数据的修改。
2.6 关闭与数据库的连接
连接对象.close()
2.7 获取执行sql语句的游标对象
获取游标对象的目标就是要执行sql语句,完成对数据库的增、删、改、查操作。
2.7.1 获取游标对象
# 调用连接对象的cursor()方法获取游标对象 cur = 连接对象.cursor()
2.7.2 游标操作说明
- 使用游标执行SQL语句:
cur.execute(operation [parameters ])
执行SQL语句,返回受影响的行数,主要用于执行insert、update、delete、select等语句 - 获取查询结果集中的一条数据:
cur.fetchone()
返回一个元组, 如 (1,‘张三’) - 获取查询结果集中的所有数据:
cur.fetchall()
返回一个元组,如((1,‘张三’),(2,‘李四’)) - 关闭游标:
cur.close()
,表示和数据库操作完成
2.8 Python 操作 MySQL 图解
3. 使用 Python 操作 MySQL
3.1 pymysql完成数据的查询操作
import pymysql # 获取连接对象 conn = pymysql.connect( host='localhost', port=3306, user='root', password='', database='atguigudb', charset='utf8' ) # 获取游标对象 cur = conn.cursor() # 查询数据库的sql语句 sql = 'select * from `order`' # 使用游标对象执行sql语句 # 并获取执行sql语句影响的行数 row_count = cur.execute(sql) print(row_count) # 通过游标对象获取查询的第一行结果 # res = cur.fetchone() # print(res) # 通过游标对象获取全部的查询结果 res = cur.fetchall() for i in res: print(i) # 关闭游标 cur.close() # 关闭连接 conn.close()
3.2 pymysql完成对数据的增加
import pymysql # 获取连接对象 conn = pymysql.connect( host='localhost', port=3306, user='root', password='', database='atguigudb', charset='utf8' ) # 获取游标对象 cur = conn.cursor() # 查询数据库的sql语句 sql = "insert into `order` values(4, 'abc')" # 使用游标对象执行sql语句 # 并获取执行sql语句影响的行数 # 由于修改数据可能会报错,所以需要进行异常的捕获 try: row_count = cur.execute(sql) print(row_count) if row_count >= 1: print('对数据进行修改成功') # 提交数据的修改 conn.commit() except Exception as e: # 如果对数据修改出现异常,则回滚数据,撤销修改 conn.rollback() # 关闭游标 cur.close() # 关闭连接 conn.close()
3.3 pymysql完成对数据的修改
import pymysql # 获取连接对象 conn = pymysql.connect( host='localhost', port=3306, user='root', password='', database='atguigudb', charset='utf8' ) # 获取游标对象 cur = conn.cursor() # 查询数据库的sql语句 sql = "update `order` set order_name='aaa' where order_id=4;" # 使用游标对象执行sql语句 # 并获取执行sql语句影响的行数 # 由于修改数据可能会报错,所以需要进行异常的捕获 try: row_count = cur.execute(sql) print(row_count) if row_count >= 1: print('对数据进行修改成功') # 提交数据的修改 conn.commit() except Exception as e: # 如果对数据修改出现异常,则回滚数据,撤销修改 conn.rollback() # 关闭游标 cur.close() # 关闭连接 conn.close()
3.4 pymysql完成对数据的删除
import pymysql # 获取连接对象 conn = pymysql.connect( host='localhost', port=3306, user='root', password='', database='atguigudb', charset='utf8' ) # 获取游标对象 cur = conn.cursor() # 查询数据库的sql语句 sql = "delete from `order` where order_id=4;" # 使用游标对象执行sql语句 # 并获取执行sql语句影响的行数 # 由于修改数据可能会报错,所以需要进行异常的捕获 try: row_count = cur.execute(sql) print(row_count) if row_count >= 1: print('对数据进行修改成功') # 提交数据的修改 conn.commit() except Exception as e: # 如果对数据修改出现异常,则回滚数据,撤销修改 conn.rollback() # 关闭游标 cur.close() # 关闭连接 conn.close()
4. 防止SQL注入
4.1 SQL注入
用户提交带有恶意的数据与SQL语句进行字符串方式的拼接,从而影响了SQL语句的语义,最终产生数据泄露的现象。
假如我们只要查询order表中order_id为1的数据,但是提交了带有恶意的数据与SQL语句进行字符串拼接,最终查询出了order表中的所有结果,这就是SQL注入。
import pymysql # 获取连接对象 conn = pymysql.connect( host='localhost', port=3306, user='root', password='', database='atguigudb', charset='utf8' ) # 获取游标对象 cur = conn.cursor() # 查询数据库的sql语句 sql = "select * from `order` where order_id='%s';" %"1' or 1=1 or '1" print('sql:', sql) # 使用游标对象执行sql语句 # 并获取执行sql语句影响的行数 row_count = cur.execute(sql) print(row_count) for i in cur.fetchall(): print(i) # 关闭游标 cur.close() # 关闭连接 conn.close()
sql: select * from
order where order_id='1' or 1=1 or '1';
,在这个sql中无论需要的查询条件是什么,拼接后的sql语句的where条件由于1=1
一定会成立,一定会查询出表中全部的结果。
4.2 防止SQL注入
SQL语句参数化:
(1)SQL语言中的参数使用%s来占位,此处不是python中的字符串格式化操作
(2)将SQL语句中%s占位所需要的参数存在一个列表中,把参数列表传递给execute方法中第二个参数
execute方法中将要执行的sql语句的 %s 占位不需要带引号
第二个参数的数据类型可以是列表、元组。
import pymysql # 获取连接对象 conn = pymysql.connect( host='localhost', port=3306, user='root', password='', database='atguigudb', charset='utf8' ) # 获取游标对象 cur = conn.cursor() # 查询数据库的sql语句 sql = "select * from `order` where order_id=%s;" # sql语句中需要的参数 params = (1,) # 使用游标对象执行sql语句 # 并获取执行sql语句影响的行数 row_count = cur.execute(sql, params) print(row_count) for i in cur.fetchall(): print(i) # 关闭游标 cur.close() # 关闭连接 conn.close()
尝试SQL注入:
import pymysql # 获取连接对象 conn = pymysql.connect( host='localhost', port=3306, user='root', password='', database='atguigudb', charset='utf8' ) # 获取游标对象 cur = conn.cursor() # 查询数据库的sql语句 sql = "select * from `order` where order_id=%s;" # sql语句中需要的参数 params = ("1' or 1=1 or '1",) # 使用游标对象执行sql语句 # 并获取执行sql语句影响的行数 row_count = cur.execute(sql, params) print(row_count) for i in cur.fetchall(): print(i) # 关闭游标 cur.close() # 关闭连接 conn.close()