目录

  1. 引言:Python 与数据库
  2. 前置准备:环境配置
    • 2.1 安装 Python
    • 2.2 安装 MySQL Server
    • 2.3 安装 mysql-connector-python
    • 2.4 准备 MySQL 数据库和表
  3. 核心步骤概览
  4. 连接到 MySQL 数据库
    • 4.1 mysql.connector.connect() 方法
    • 4.2 错误处理与连接参数
  5. 创建游标对象 (Cursor)
  6. 单行数据插入 (INSERT Single Row)
    • 6.1 SQL INSERT 语句基础
    • 6.2 安全性核心:使用占位符 (%)
    • 6.3 cursor.execute() 方法
    • 6.4 提交更改 (conn.commit())
    • 6.5 完整代码示例
  7. 多行数据插入 (INSERT Multiple Rows / Batch Insertion)
    • 7.1 cursor.executemany() 方法
    • 7.2 准备多行数据
    • 7.3 完整代码示例
  8. 错误处理与事务管理
    • 8.1 try-except-finally 结构
    • 8.2 回滚操作 (conn.rollback())
  9. 关闭数据库连接和游标
    • 9.1 cursor.close()
    • 9.2 conn.close()
    • 9.3 使用 with 语句实现自动资源管理 (推荐)
  10. 最佳实践与注意事项
    • 10.1 SQL 注入防护
    • 10.2 事务管理的重要性
    • 10.3 清理资源
    • 10.4 密码安全
    • 10.5 数据类型映射
    • 10.6 性能考量
  11. 总结

1. 引言:Python 与数据库

在现代 Web 开发、数据科学和自动化任务中,Python 经常需要与数据库进行交互,其中关系型数据库 MySQL 是最受欢迎的选择之一。将数据存储到数据库是许多应用程序的核心功能。本指南将专注于演示如何使用 Python 将数据插入到 MySQL 数据库表中,这是数据库操作中最基本且频繁的需求。

2. 前置准备:环境配置

在开始编写 Python 代码之前,您需要确保以下环境已配置好:

2.1 安装 Python

确保您的系统上已安装 Python 3。可以从 python.org 下载最新版本。

2.2 安装 MySQL Server

您需要在本地或远程服务器上安装并运行 MySQL 数据库。您可以从 mysql.com 下载 MySQL Community Server。

2.3 安装 mysql-connector-python

Python 需要一个连接器库来与 MySQL 数据库通信。官方推荐的连接器是 mysql-connector-python
通过 pip 安装:

pip install mysql-connector-python

2.4 准备 MySQL 数据库和表

为了演示,我们假设您已经创建了一个名为 mydatabase 的数据库,并且在该数据库中有一个名为 customers 的表。如果还没有,请使用 MySQL 客户端(如 MySQL Workbench 或命令行)创建它们:

-- 创建数据库
CREATE DATABASE IF NOT EXISTS mydatabase;

-- 使用数据库
USE mydatabase;

-- 创建表
CREATE TABLE IF NOT EXISTS customers (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    address VARCHAR(255)
);

3. 核心步骤概览

无论是插入单行还是多行数据,通常都遵循以下核心步骤:

  1. 导入 mysql.connector 模块。
  2. 建立连接 到 MySQL 数据库。
  3. 创建游标对象,用于执行 SQL 查询。
  4. 定义 SQL INSERT 语句
  5. 准备要插入的数据
  6. 执行 SQL 查询,将数据传递给游标。
  7. 提交 (Commit) 事务,使更改永久生效。
  8. 关闭游标和连接,释放资源。

4. 连接到 MySQL 数据库

这是与数据库交互的第一步。

4.1 mysql.connector.connect() 方法

使用 mysql.connector.connect() 函数来建立连接。它需要一些参数来指定数据库的位置和凭据。

常用参数:

  • host: MySQL 服务器的主机名或 IP 地址(例如 ‘localhost’, ‘127.0.0.1’)。
  • user: 连接数据库的用户名(例如 ‘root’)。
  • password: 对应用户的密码。
  • database: 要连接的数据库名称。
import mysql.connector

try:
    conn = mysql.connector.connect(
        host="localhost",
        user="your_username",     # 替换为您的 MySQL 用户名
        password="your_password", # 替换为您的 MySQL 密码
        database="mydatabase"
    )
    if conn.is_connected():
        print("成功连接到 MySQL 数据库!")

except mysql.connector.Error as err:
    print(f"连接失败: {err}")
    conn = None # 如果连接失败,将 conn 设置为 None

注意: 将 your_usernameyour_password 替换为您的实际 MySQL 凭据。

5. 创建游标对象 (Cursor)

连接成功后,需要创建一个游标对象。游标是数据库中的一个临时工作区,用于执行 SQL 语句并检索查询结果。

# 假设 conn 已经成功建立
if conn:
    cursor = conn.cursor()
    print("游标对象已创建。")
else:
    print("数据库连接未建立,无法创建游标。")

6. 单行数据插入 (INSERT Single Row)

6.1 SQL INSERT 语句基础

标准的 SQL INSERT 语句用于向表中添加新行。

INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);

对于我们的 customers 表,它看起来像这样:

INSERT INTO customers (name, address) VALUES ('John Doe', 'Highway 21');

6.2 安全性核心:使用占位符 (%)

这是最重要的一点! 在 Python 中执行 SQL 插入时,绝不能直接将用户输入或变量值拼接到 SQL 字符串中。这样做会使您的应用程序面临严重的SQL 注入风险。

相反,您应该使用占位符mysql-connector-python 库使用 %s 作为占位符。库会自动处理数据转义,防止恶意输入。

sql = "INSERT INTO customers (name, address) VALUES (%s, %s)"

6.3 cursor.execute() 方法

cursor.execute() 方法用于执行 SQL 查询。对于带占位符的查询,它接受两个参数:

  1. SQL 查询字符串。
  2. 一个包含要插入数据的元组 (tuple)列表 (list)。数据顺序必须与 SQL 语句中的列顺序相对应。
name = "John Doe"
address = "Highway 21"
val = (name, address) # 数据以元组形式传递

cursor.execute(sql, val)

6.4 提交更改 (conn.commit())

默认情况下,mysql-connector-python 库会以事务模式运行。这意味着您执行的任何更改(如 INSERT, UPDATE, DELETE)在您显式调用 conn.commit() 之前都不会永久保存到数据库中。这允许您在发现错误时使用 conn.rollback() 撤销更改。

conn.commit()
print(f"数据插入成功,已插入 {cursor.rowcount} 行。")

6.5 完整代码示例 (单行插入)

import mysql.connector

conn = None # 初始化连接对象为 None
cursor = None # 初始化游标对象为 None

try:
    conn = mysql.connector.connect(
        host="localhost",
        user="your_username",
        password="your_password",
        database="mydatabase"
    )

    if conn.is_connected():
        print("成功连接到 MySQL 数据库!")
        cursor = conn.cursor()

        # 定义 SQL INSERT 语句,使用 %s 作为占位符
        sql = "INSERT INTO customers (name, address) VALUES (%s, %s)"

        # 准备要插入的数据(单个元组)
        name_to_insert = "Company Inc"
        address_to_insert = "Highway 37"
        val = (name_to_insert, address_to_insert)

        # 执行查询
        cursor.execute(sql, val)

        # 提交更改到数据库
        conn.commit()

        print(f"{cursor.rowcount} 行数据已插入。")
        print(f"新插入行的 ID: {cursor.lastrowid}") # 获取自增 ID (如果存在)

except mysql.connector.Error as err:
    print(f"数据库操作失败: {err}")
    if conn:
        conn.rollback() # 如果出错,回滚事务
        print("事务已回滚。")

finally:
    if cursor:
        cursor.close()
    if conn and conn.is_connected():
        conn.close()
        print("MySQL 连接已关闭。")

7. 多行数据插入 (INSERT Multiple Rows / Batch Insertion)

当需要插入多行数据时,使用 cursor.executemany() 比多次调用 cursor.execute() 更高效。

7.1 cursor.executemany() 方法

cursor.executemany() 方法接受两个参数:

  1. SQL 查询字符串(同样使用 %s 占位符)。
  2. 一个包含多个数据元组的列表 (list)。每个元组代表要插入的一行数据。

7.2 准备多行数据

数据应该是一个列表,其中每个元素都是一个元组,每个元组的项与 SQL 语句中的占位符一一对应。

data = [
    ("Amy", "Apple St 652"),
    ("Hannah", "Mountain St 34"),
    ("Michael", "Valley 345"),
    ("Sandy", "Ocean blvd 255"),
    ("Betty", "Park Lane 900")
]

7.3 完整代码示例 (多行插入)

import mysql.connector

conn = None
cursor = None

try:
    conn = mysql.connector.connect(
        host="localhost",
        user="your_username",
        password="your_password",
        database="mydatabase"
    )

    if conn.is_connected():
        print("成功连接到 MySQL 数据库!")
        cursor = conn.cursor()

        # 定义 SQL INSERT 语句
        sql = "INSERT INTO customers (name, address) VALUES (%s, %s)"

        # 准备多行数据
        data_to_insert = [
            ("Amy", "Apple St 652"),
            ("Hannah", "Mountain St 34"),
            ("Michael", "Valley 345"),
            ("Sandy", "Ocean blvd 255"),
            ("Betty", "Park Lane 900")
        ]

        # 执行批量插入
        cursor.executemany(sql, data_to_insert)

        # 提交更改
        conn.commit()

        print(f"{cursor.rowcount} 行数据已批量插入。")

except mysql.connector.Error as err:
    print(f"数据库操作失败: {err}")
    if conn:
        conn.rollback() # 出错时回滚
        print("事务已回滚。")

finally:
    if cursor:
        cursor.close()
    if conn and conn.is_connected():
        conn.close()
        print("MySQL 连接已关闭。")

8. 错误处理与事务管理

健壮的应用程序必须包含适当的错误处理。

8.1 try-except-finally 结构

  • try 块包含可能会引发异常的代码(如连接数据库、执行查询)。
  • except mysql.connector.Error as err 块捕获 mysql.connector 模块可能抛出的所有错误。
  • finally 块确保无论是否发生异常,资源(如游标和连接)都会被关闭。

8.2 回滚操作 (conn.rollback())

在事务中(即在 conn.commit() 之前),如果发生任何错误,您可以通过调用 conn.rollback() 来撤销所有未提交的更改。这确保了数据库的原子性 (Atomicity),即事务要么全部成功,要么全部失败,不会出现部分完成的状态。

9. 关闭数据库连接和游标

9.1 cursor.close()

在完成所有 SQL 操作后,应该关闭游标对象,释放其关联的资源。

9.2 conn.close()

在所有数据库操作完成后,关闭数据库连接是至关重要的。这会释放数据库服务器上的连接资源。

9.3 使用 with 语句实现自动资源管理 (推荐)

Python 的 with 语句是管理资源(如文件、数据库连接)的推荐方式。它确保资源在使用完毕后(无论是否发生错误)都能被正确关闭。mysql.connector 的连接对象和游标对象都支持上下文管理器协议。

import mysql.connector

try:
    with mysql.connector.connect(
        host="localhost",
        user="your_username",
        password="your_password",
        database="mydatabase"
    ) as conn:
        print("成功连接到 MySQL 数据库!")
        with conn.cursor() as cursor:
            # 单行插入示例
            sql_single = "INSERT INTO customers (name, address) VALUES (%s, %s)"
            val_single = ("Grace", "Pineapple St 101")
            cursor.execute(sql_single, val_single)
            conn.commit()
            print(f"{cursor.rowcount} 行数据已插入。")

            # 多行插入示例
            sql_multi = "INSERT INTO customers (name, address) VALUES (%s, %s)"
            data_multi = [
                ("Frank", "Cherry Lane 202"),
                ("Ivy", "Grapefruit Ave 303")
            ]
            cursor.executemany(sql_multi, data_multi)
            conn.commit()
            print(f"{cursor.rowcount} 行数据已批量插入。")

except mysql.connector.Error as err:
    print(f"数据库操作失败: {err}")
    # 在 with 语句中,如果发生异常,conn.rollback() 会自动被调用
    # 但显式调用有时能更好地控制,取决于具体错误处理逻辑
    # 如果conn仍然有效,可以在这里手动回滚
    if 'conn' in locals() and conn.is_connected():
        conn.rollback()
        print("事务已回滚。")

使用 with 语句,您无需手动调用 conn.close()cursor.close(),它们会在 with 块结束时自动调用。

10. 最佳实践与注意事项

10.1 SQL 注入防护

再次强调,永远不要直接将用户输入拼接到 SQL 语句中。始终使用占位符(%s)和 cursor.execute()cursor.executemany() 的参数化查询功能。这是防止 SQL 注入攻击的黄金法则。

10.2 事务管理的重要性

理解 commit()rollback() 的作用。对于任何修改数据的操作,确保在所有相关操作成功后才 commit()。如果中间任何一步失败,应 rollback() 以保持数据一致性。

10.3 清理资源

及时关闭游标和连接。使用 with 语句是最佳选择。未关闭的连接会耗尽数据库服务器的资源,导致性能问题或服务不可用。

10.4 密码安全

在生产环境中,绝不应该将数据库密码硬编码在代码中。应使用环境变量、配置文件或秘密管理服务来安全地存储和检索数据库凭据。

10.5 数据类型映射

Python 数据类型会自动映射到 MySQL 的数据类型。例如:

  • Python int -> MySQL INT
  • Python float -> MySQL FLOATDOUBLE
  • Python str -> MySQL VARCHAR, TEXT
  • Python bool -> MySQL TINYINT(1) (0 或 1)
  • Python datetime 对象 -> MySQL DATETIMETIMESTAMP

10.6 性能考量

  • 批量插入: 对于大量数据,cursor.executemany() 比循环调用 cursor.execute() 效率高得多。
  • 索引: 确保您的数据库表有适当的索引,这对于查询性能和数据插入效率都很重要。
  • 缓冲: 默认情况下,mysql-connector-python 不会缓冲结果集。如果处理非常大的结果集,可以考虑配置游标为缓冲模式(buffered=True),但这会占用更多内存。对于插入操作,通常不是问题。

11. 总结

为您深度解析了如何使用 Python 向 MySQL 数据库插入数据。

核心要点回顾:

  • 首先,确保您已安装 PythonMySQL Servermysql-connector-python
  • 通过 mysql.connector.connect() 建立数据库连接,并通过 cursor() 创建游标。
  • 使用 cursor.execute() 插入单行数据,使用 cursor.executemany() 批量插入多行数据。
  • 最重要的是,始终使用 %s 占位符来传递数据,以有效防止 SQL 注入攻击。
  • 通过 conn.commit() 提交更改使数据永久化,通过 conn.rollback() 在出错时撤销更改。
  • 使用 try-except-finally 结构或 with 语句来安全地管理和关闭数据库资源。

掌握这些技术将使您能够安全、高效地管理 Python 应用程序中的 MySQL 数据插入任务。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐