今天主要学习数据库的编程练习,使用pyharm进行数据库的操作。
重要内容:
- sql注入:就是利用正常的sql语句,获取到了非法的数据(参数化可以解决)
- 使用pymysql模块进行数据库编程,实现查询、插入、删除、改数据等操作。
- 五个步骤:
- 创建数据库的连接
- 数据库服务器的主机地址
- 数据库服务器端口
- 用户名
- 密码
- 数据库名
- 字符集
- 获取游标对象
- 执行sql操作
- 关闭游标
- 关闭数据库的连接
- 具体代码实现
from pymysql import Connect
db_count = Connect(host='localhost',port=3306,database='python_db',user='root',password='mysql',charset='utf8')
cur = db_count.cursor()
sql_str = """要执行的SQL语句"""
cur.execute(sql_str)
db_count.commit()
cur.close()
db_count.close()
上课所用代码:
1. 数据库编程
统一时刻只有一个游标存活cursor
""" 使用pymysql模块进行数据库编程 实现查询操作 0 导入模块 1 创建数据库连接 2 获取游标对象 3 执行sql操作 4 关闭游标 5 关闭数据库连接 """ # 0导入模块 from pymysql import connect # 1创建数据库连接 # 6个参数 # 参数一:数据库服务器的主机地址 # 参数二:数据库服务器端口 # 参数三:用户名 # 参数四:密码 # 参数五:数据库名 # 参数六:字符集 # 注意: # 参数因为使用关键字参数,可以无序 # 除端口号用整数类型外,其余参数全部使用字符串 db_connect = connect(host='localhost',port=3306,user = 'root',password='mysql',database='python_db',charset='utf8') # 2获取游标对象 cur = db_connect.cursor() # 3执行sql操作 # 准备sql指令字符串 # sql_str = """select * from students where name ="小明";""" sql_str = """select * from students;""" row_count = cur.execute(sql_str) print('sql操作一共影响了 %d 行数据' % row_count) print('sql操作一共影响了 %d 行数据' % cur.rowcount) print('sql操作一共影响了 %d 行数据' % cur.rownumber) print('*'*30) # 获取查询结果 # 方法一: 获取单条数据(返回结果是一个元祖) result = cur.fetchone() print(result) print('*'*30) # 方式二 获取指定条数的数据(返回值是一个嵌套的元祖) result = cur.fetchmany(4) for t in result: print(t) print('*'*30) # 方式三 获取所有的数据(返回值嵌套的元祖) result = cur.fetchall() for t in result: print(t) print('*'*30) # 滚动游标 # cur.scroll(-10,'relative') 相对移动游标,负数是向回移动 cur.scroll(1,'absolute') # 绝对移动,参数一是移动的数据的索引,从0开始计数 result = cur.fetchall() for t in result: print(t) print('*'*30) # 4关闭游标 cur.close() # 5关闭数据库连接 db_connect.close()
1.1增删改查
增
""" 使用pymysql模块向数据库中插入数据 当获取一个游标对象时,游标会自动开启一个隐式的事务 """ from pymysql import Connect db_count = Connect(host='localhost',port=3306,database='python_db',user='root',password='mysql',charset='utf8') cur = db_count.cursor() sql_str = """insert into students (name) values ('王刚蛋');""" cur.execute(sql_str) # 当执行玩增删改操作之后,需要去操作进行提交,(实际上是对事务进行提交) # 如果不做提交操作,那么当关闭数据库时,数据库会默认回滚 db_count.commit() cur.close() db_count.close()
删
from pymysql import Connection db_count = Connection(host='localhost',port=3306,database='python_db',user='root',password='mysql',charset='utf8') cur = db_count.cursor() sql_str = """delete from students where name = '王刚蛋'""" cur.execute(sql_str) # 当执行玩增删改操作之后,需要去操作进行提交,(实际上是对事务进行提交) # 如果不做提交操作,那么当关闭数据库时,数据库会默认回滚 db_count.commit() cur.close() db_count.close()
改
from pymysql import Connection db_count = Connection(host='localhost',port=3306,database='python_db',user='root',password='mysql',charset='utf8') cur = db_count.cursor() sql_str = """update students set height = 165 where name = '周杰伦'""" cur.execute(sql_str) # 当执行玩增删改操作之后,需要去操作进行提交,(实际上是对事务进行提交) # 如果不做提交操作,那么当关闭数据库时,数据库会默认回滚 db_count.commit() cur.close() db_count.close()
自动提交
"""开启自动提交(了解)一般都是手动提交""" from pymysql import connect db_connect = connect(host='localhost',port=3306,database='python_db',user='root',password='mysql',charset ='utf8') # 开启自动提交 db_connect.autocommit(True) cur = db_connect.cursor() sql_str = """insert into students (name) values ('王钢蛋 %d 号')""" for i in range(5): cur.execute(sql_str % i) cur.close() db_connect.close()
事务操作
""" 当创建游标对象时,游标对象会默认开启一个隐式事务 可以通过commit提交 可以通过rollback回滚 如果没有任何操作时,当数据库关闭,那么会默认执行回滚操作 """ # 导入模块 import random from pymysql import connect db_connect = connect(host='localhost',port=3306,user='root',password='mysql',database='python_db',charset='utf8') cur = db_connect.cursor() # 默认会开启一个事务 sql_str = """insert into students (name) values ('铁锤妹妹')""" try: for i in range(5): cur.execute(sql_str) # 取一个随机数来判断是否成功 n = random.randint(0,1) if n == 0: print('------------',n) # 说明出错了,去抛出一个异常 raise Exception except Exception as e: print('出现异常,进行数据回滚') # 使用数据库对象进行回滚操作 db_connect.rollback() # 虽然出错,但是自动增长会被记录,下次提交成功的话,自动增长会从上次记录的地方开始 else: print('数据提交成功') db_connect.commit() finally: cur.close() db_connect.close()
1.2 SQL注入
什么是SQL注入?
- 产生原因: 后台对用户提交的带有恶意的数据和 SQL 进行字符串方式的拼接,得到了脱离原意的 SQL 语句,从而影响了 SQL 语句的语义,最终产生数据泄露的现象。
- 如何防止: SQL 语句的参数化, 将 SQL 语句的所有数据参数存在一个列表中传递给 execute 函数的第二个参数
SQL注入利用了SQL语法正常规则,得到了不该得到的非法数据,导致了数据泄露
解决办法:参数化
""" SQL注入是利用了SQL语法的正常规则,得到了不该得到的非法数据,导致数据泄露 解决办法,使用参数化 """ from pymysql import * db_connect = Connect(host='localhost',port=3306,database='python_db',user='root',password='mysql',charset='utf8') cur = db_connect.cursor() # 请输入一个查询的ID query_id = input('please input ID:') # 查询 指定的ID数据 # sql_str = """select * from students where id = %s""" % query_id # print(sql_str) # cur.execute(sql_str) # 使用参数化来解决SQL注入 sql_str = """select * from students where id =%s""" # 在准备sql字符串时,不能再直接拼接参数 # 而是将参数做成一个元祖,列表字典,传入到execute 方法中 # 这种方式就是参数化 params = (query_id,) # params = [query_id] # params = {'name_id':query_id} # sql_str = """select * from students where id = %(name_id)s""" # 'root\'--' cur.execute(sql_str,params) result = cur.fetchall() for t in result: print(t)