数据库编程练习

2019-07-18 10:59:52 浏览数 (1)

今天主要学习数据库的编程练习,使用pyharm进行数据库的操作。

重要内容:


  1. sql注入:就是利用正常的sql语句,获取到了非法的数据(参数化可以解决)
  2. 使用pymysql模块进行数据库编程,实现查询、插入、删除、改数据等操作。
  3. 五个步骤
    1. 创建数据库的连接
      1. 数据库服务器的主机地址
      2. 数据库服务器端口
      3. 用户名
      4. 密码
      5. 数据库名
      6. 字符集
    2. 获取游标对象
    3. 执行sql操作
    4. 关闭游标
    5. 关闭数据库的连接
  4. 具体代码实现

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

代码语言:javascript复制
"""
    使用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增删改查

代码语言:javascript复制
"""
    使用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()

代码语言:javascript复制
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()

代码语言:javascript复制
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()

自动提交

代码语言:javascript复制
"""开启自动提交(了解)一般都是手动提交"""
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()

事务操作

代码语言:javascript复制
"""
    当创建游标对象时,游标对象会默认开启一个隐式事务
    可以通过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语法正常规则,得到了不该得到的非法数据,导致了数据泄露

解决办法:参数化

代码语言:javascript复制
"""
    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)

0 人点赞