IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> [阶段二] 6. MySQL与Python交互 -> 正文阅读

[大数据][阶段二] 6. MySQL与Python交互

mysql 与 python 交互

  • Connector 模块语法:

MySQL Connector 是 mysql 官方的驱动模块,兼容性非常好。下载地址:https://dev.mysql.com/downloads/connector/python/

# coding:utf-8

import mysql.connector

# 创建连接
con = mysql.connector.connect(
    host="localhost", port="3306",
    user="root", password="123456789",
    database="demo"
)

# 关闭连接
con.close()

MySQL Connector 里面的游标(cursor)用来执行 sql 语句,而且查询的结果集也会保存在游标之中。

# coding:utf-8

import mysql.connector

# 创建连接
con = mysql.connector.connect(
    host="localhost", port="3306",
    user="root", password="123456789",
    database="vega"
)

# 执行sql
cursor = con.cursor()
sql = "SELECT username,password,email,role_id FROM t_user;"
cursor.execute(sql)

for result in cursor:
    print(result[0], result[1], result[2], result[3])

# 关闭连接
con.close()
  • sql 的注入攻击:

由于 sql 语句是解释型语言,所以在拼接 sql 语句的时候,容易被注入恶意的 sql 语句。

sql 注入攻击示例:

# coding:utf-8

import mysql.connector

config = {
    "host": "localhost",
    "port": "3306",
    "user": "root",
    "password": "123456789",
    "database": "vega"
}

con = mysql.connector.connect(**config)

username = "1 OR True"
password = "1 OR True"
sql = "SELECT COUNT(*) FROM t_user WHERE username=%s AND AES_DECRYPT(UNHEX(password),'HelloWorld')=%s;"

cursor = con.cursor()
cursor.execute(sql % (username, password))
print(cursor.fetchone()[0])

con.close()

即使攻击者不知道真实的账号密码,他也可以使用 1 OR True 这样的账号密码来注入他想要执行的恶意的 sql 语句,好在 sql 注入攻击是可以被 sql 预编译机制抵御的。

mysql 有一个 sql 预编译机制,预编译 sql 就是数据库提前把 sql 语句编译成二进制,这样反复执行同一条 sql 语句的效率就会大大提升。

sql 语句编译的过程中,关键字已经被解析过了,所以想编译后的 sql 语句传入参数,都会被当作字符串处理,数据库不会解析其中注入的 sql 语句。

预防 sql 注入攻击示例:

# coding:utf-8

import mysql.connector

config = {
    "host": "localhost",
    "port": "3306",
    "user": "root",
    "password": "123456789",
    "database": "vega"
}

con = mysql.connector.connect(**config)

username = "1 OR True"
password = "1 OR True"
sql = "SELECT COUNT(*) FROM t_user WHERE username=%s AND AES_DECRYPT(UNHEX(password),'HelloWorld')=%s;"

cursor = con.cursor()
cursor.execute(sql, (username, password))               #提前编译 sql 语句,传入参数会被当作字符串处理
print(cursor.fetchone()[0])

con.close()

通常,用户登录时容易被 sql 注入,因此不要相信用户的输入,时刻进行筛选,永远进行 sql 预编译机制。

  • Connector 的异常处理:

Connector 提供了非常简单的事务控制函数。

# coding:utf-8

import mysql.connector

con = mysql.connector.connect(
    host="localhost", port="3306",
    user="root", password="123456789",
    database="vega"
)

# 开启事务
con.start_transaction(isolation_level='repeatable read')                #参数 isolation_level 指定事务隔离级别

# 提交事务
con.commit()

# 回滚事务
con.rollback()

con.close()

Connector 的异常处理:

# coding:utf-8

import mysql.connector

try:
    con = mysql.connector.connect(
        host="localhost", port="3306",
        user="root", password="123456789",
        database="vega"
    )

    con.start_transaction(isolation_level='repeatable read')
    
    # 执行 sql 语句
    cursor = con.cursor()
    sql = "INSERT INTO t_user(username,password,email,role_id) " \
          "VALUES('bai', HEX(AES_ENCRYPT('123456','HelloWorld')),'bai@bai.com', 3);"
    cursor.execute(sql)
    
    con.commit()

except Exception as e:
    if "con" in dir():
        con.rollback()
    print(e)

finally:
    if "con" in dir():
        con.close()
  • 数据库连接池:

TCP 连接往往需要经过三次握手、四次挥手来建立和关闭,然后数据库还要验证用户信息。因此数据库连接是一种关键的、有限的、昂贵的资源,在并发执行的应用程序中体现得尤为突出。

数据库连接池会预先创建出一些数据库连接,然后缓存起来,避免了程序语言反复创建和销毁连接的昂贵代价。

# coding:utf-8

import mysql.connector.pooling

config = {
    "host": "localhost",
    "port": "3306",
    "user": "root",
    "password": "123456789",
    "database": "vega"
}

try:
    # 创建连接池
    pool = mysql.connector.pooling.MySQLConnectionPool(
        **config,
        pool_size=10
    )
    
    # 获取连接池的连接
    con = pool.get_connection()
    
    con.start_transaction(isolation_level='repeatable read')
    cursor = con.cursor()
    sql = "UPDATE t_user SET username=%s WHERE role_id=%s;"
    cursor.execute(sql, ('xiaohei', 3))
    con.commit()
    
except Exception as e:
    if "con" in dir():
        con.rollback()
    print(e)
  • Connector 删除数据:
# coding:utf-8

import mysql.connector.pooling

config = {
    "host": "localhost",
    "port": "3306",
    "user": "root",
    "password": "123456789",
    "database": "vega"
}

try:
    pool = mysql.connector.pooling.MySQLConnectionPool(
        **config,
        pool_size=10
    )

    con = pool.get_connection()

    con.start_transaction(isolation_level='repeatable read')
    cursor = con.cursor()
    sql = "DELETE IGNORE FROM t_user WHERE username=%s;"
    cursor.execute(sql, ('xiaohei',))
    con.commit()

except Exception as e:
    if "con" in dir():
        con.rollback()
    print(e)

如果是使用 TRUNCATE TABLE 数据表名称; 来清空数据表,则不需要开启事务。

另外,游标对象中的 executemany 函数可以反复执行一条 sql 语句。

# coding:utf-8

import mysql.connector.pooling

config = {
    "host": "localhost",
    "port": "3306",
    "user": "root",
    "password": "123456789",
    "database": "vega"
}

try:
    pool = mysql.connector.pooling.MySQLConnectionPool(
        **config,
        pool_size=10
    )

    con = pool.get_connection()

    con.start_transaction(isolation_level='repeatable read')
    cursor = con.cursor()
    sql = "INSERT INTO t_user(username,password,email,role_id) " \
          "VALUES(%s, HEX(AES_ENCRYPT('123456','HelloWorld')),%s, %s);"
    person_list = [['aaa', 'aaa@aaa.com', 3], ['bbb', 'bbb@bbb.com', 4], ['ccc', 'ccc@ccc.com', 5]]
    cursor.executemany(sql, person_list)                # 反复执行 sql 语句
    con.commit()

except Exception as e:
    if "con" in dir():
        con.rollback()
    print(e)

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 13:58:47  更:2022-01-01 13:58:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 13:31:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码