python-pymysql
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePyMySQL Best Practices
PyMySQL 最佳实践
PyMySQL is a pure-Python MySQL client library implementing the DB-API 2.0 specification (PEP 249). It supports MySQL >= 5.7 and MariaDB >= 10.3 on Python >= 3.7.
PyMySQL是一个纯Python编写的MySQL客户端库,实现了DB-API 2.0规范(PEP 249)。它支持Python >= 3.7环境下的MySQL >= 5.7和MariaDB >= 10.3。
Installation
安装
bash
pip install PyMySQLbash
pip install PyMySQLFor SHA-256 / caching_sha2_password authentication:
如需SHA-256 / caching_sha2_password认证:
pip install "PyMySQL[rsa]"
undefinedpip install "PyMySQL[rsa]"
undefinedEstablishing a Connection
建立连接
Use as the entry point. Always specify and use context managers to guarantee cleanup.
pymysql.connect()charset='utf8mb4'python
import pymysql
import pymysql.cursors
connection = pymysql.connect(
host="localhost",
user="app_user",
password="secret",
database="mydb",
charset="utf8mb4",
cursorclass=pymysql.cursors.DictCursor,
connect_timeout=10,
read_timeout=30,
write_timeout=30,
autocommit=False, # explicit transaction control (recommended)
)使用作为入口点。请始终指定,并使用上下文管理器确保资源清理。
pymysql.connect()charset='utf8mb4'python
import pymysql
import pymysql.cursors
connection = pymysql.connect(
host="localhost",
user="app_user",
password="secret",
database="mydb",
charset="utf8mb4",
cursorclass=pymysql.cursors.DictCursor,
connect_timeout=10,
read_timeout=30,
write_timeout=30,
autocommit=False, # 显式事务控制(推荐)
)Key Connection Parameters
关键连接参数
| Parameter | Default | Notes |
|---|---|---|
| | Always set |
| | Use |
| | Keep |
| | Seconds before connection attempt fails |
| | Set to prevent hung reads |
| | Set to prevent hung writes |
| | Path to CA cert for TLS connections |
| 参数 | 默认值 | 说明 |
|---|---|---|
| | 始终设置为 |
| | 使用 |
| | 保持为 |
| | 连接尝试失败前的等待秒数 |
| | 设置该值以防止读取操作挂起 |
| | 设置该值以防止写入操作挂起 |
| | TLS连接使用的CA证书路径 |
Context Manager Usage
上下文管理器用法
Connections and cursors implement the context manager protocol. Use blocks to ensure proper resource cleanup.
withpython
undefined连接和游标实现了上下文管理器协议。使用语句块确保资源被正确清理。
withpython
undefinedConnection as context manager — commits on success, rolls back on exception
连接作为上下文管理器——成功时提交,异常时回滚
with pymysql.connect(**db_config) as connection:
with connection.cursor() as cursor:
cursor.execute("SELECT id, email FROM users WHERE active = %s", (1,))
rows = cursor.fetchall()
> **Note**: Using `with connection:` handles transaction commit/rollback but does **not** close the connection. Call `connection.close()` explicitly or manage it via a pool.with pymysql.connect(**db_config) as connection:
with connection.cursor() as cursor:
cursor.execute("SELECT id, email FROM users WHERE active = %s", (1,))
rows = cursor.fetchall()
> **注意**:使用`with connection:`会处理事务的提交/回滚,但**不会**关闭连接。请显式调用`connection.close()`或通过连接池管理连接。Parameterized Queries (SQL Injection Prevention)
参数化查询(防止SQL注入)
Always pass values as the second argument to . Never use string formatting or concatenation to build SQL.
execute()python
undefined请始终将值作为的第二个参数传入。切勿使用字符串格式化或拼接来构建SQL语句。
execute()python
undefinedCorrect — parameterized
正确方式——参数化查询
cursor.execute(
"INSERT INTO orders (user_id, amount) VALUES (%s, %s)",
(user_id, amount),
)
cursor.execute(
"INSERT INTO orders (user_id, amount) VALUES (%s, %s)",
(user_id, amount),
)
Named placeholders with dict
使用字典的命名占位符
cursor.execute(
"SELECT * FROM products WHERE category = %(cat)s AND price < %(max_price)s",
{"cat": "electronics", "max_price": 500},
)
cursor.execute(
"SELECT * FROM products WHERE category = %(cat)s AND price < %(max_price)s",
{"cat": "electronics", "max_price": 500},
)
WRONG — never do this
错误方式——切勿这样做
cursor.execute(f"SELECT * FROM users WHERE name = '{name}'") # SQL injection risk
Use `cursor.mogrify(query, args)` to preview the interpolated query string during debugging.cursor.execute(f"SELECT * FROM users WHERE name = '{name}'") # 存在SQL注入风险
调试期间,可使用`cursor.mogrify(query, args)`预览插值后的查询字符串。Cursor Types
游标类型
| Cursor Class | Returns | Buffered | Use Case |
|---|---|---|---|
| tuple | Yes | Default; small-to-medium result sets |
| dict | Yes | When column-name access is needed |
| tuple | No | Large result sets; memory-constrained |
| dict | No | Large result sets with dict access |
Pass at connection time (global default) or per-cursor:
cursorclasspython
undefined| 游标类 | 返回格式 | 是否缓冲 | 使用场景 |
|---|---|---|---|
| 元组 | 是 | 默认类型;适用于中小型结果集 |
| 字典 | 是 | 需要按列名访问数据时使用 |
| 元组 | 否 | 大型结果集;内存受限场景 |
| 字典 | 否 | 需要字典格式的大型结果集场景 |
可在连接时指定(全局默认),或为每个游标单独设置:
cursorclasspython
undefinedPer-cursor override
为单个游标覆盖全局设置
with connection.cursor(pymysql.cursors.DictCursor) as cursor:
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall() # list of dicts
For large tables, prefer `SSCursor` and iterate without calling `fetchall()`:
```python
with connection.cursor(pymysql.cursors.SSCursor) as cursor:
cursor.execute("SELECT * FROM large_table")
for row in cursor: # streams row-by-row
process(row)with connection.cursor(pymysql.cursors.DictCursor) as cursor:
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall() # 字典列表
处理大表时,优先使用`SSCursor`并逐行迭代,避免调用`fetchall()`:
```python
with connection.cursor(pymysql.cursors.SSCursor) as cursor:
cursor.execute("SELECT * FROM large_table")
for row in cursor: # 逐行流式处理
process(row)Transaction Management
事务管理
PyMySQL defaults to . Explicitly commit successful work and roll back on errors.
autocommit=Falsepython
try:
with connection.cursor() as cursor:
cursor.execute(
"UPDATE accounts SET balance = balance - %s WHERE id = %s",
(amount, from_id),
)
cursor.execute(
"UPDATE accounts SET balance = balance + %s WHERE id = %s",
(amount, to_id),
)
connection.commit()
except Exception:
connection.rollback()
raiseCall to start a transaction block explicitly when needed.
connection.begin()PyMySQL默认。请为成功的操作显式提交,出错时回滚。
autocommit=Falsepython
try:
with connection.cursor() as cursor:
cursor.execute(
"UPDATE accounts SET balance = balance - %s WHERE id = %s",
(amount, from_id),
)
cursor.execute(
"UPDATE accounts SET balance = balance + %s WHERE id = %s",
(amount, to_id),
)
connection.commit()
except Exception:
connection.rollback()
raise必要时,可调用显式启动事务块。
connection.begin()Bulk Inserts with executemany()
executemany()使用executemany()
批量插入
executemany()Use for inserting multiple rows. PyMySQL batches the statements up to (1 MB) for efficiency.
executemany()Cursor.max_stmt_lengthpython
records = [
("alice@example.com", "hash1"),
("bob@example.com", "hash2"),
]
with connection.cursor() as cursor:
cursor.execute("TRUNCATE TABLE staging_users")
cursor.executemany(
"INSERT INTO users (email, password_hash) VALUES (%s, %s)",
records,
)
connection.commit()使用插入多行数据。PyMySQL会将语句分批处理,最大批次大小为(1 MB)以提升效率。
executemany()Cursor.max_stmt_lengthpython
records = [
("alice@example.com", "hash1"),
("bob@example.com", "hash2"),
]
with connection.cursor() as cursor:
cursor.execute("TRUNCATE TABLE staging_users")
cursor.executemany(
"INSERT INTO users (email, password_hash) VALUES (%s, %s)",
records,
)
connection.commit()Fetching Rows
行数据获取
| Method | Returns | Notes |
|---|---|---|
| single row or | Efficient for single-row lookups |
| list of rows | Page through results |
| list of all rows | Avoid on large result sets |
python
cursor.execute("SELECT id, name FROM users WHERE id = %s", (user_id,))
row = cursor.fetchone()
if row is None:
raise ValueError(f"User {user_id} not found")| 方法 | 返回值 | 说明 |
|---|---|---|
| 单行数据或 | 高效查找单行数据 |
| 行数据列表 | 分页获取结果 |
| 所有行数据列表 | 大型结果集请避免使用 |
python
cursor.execute("SELECT id, name FROM users WHERE id = %s", (user_id,))
row = cursor.fetchone()
if row is None:
raise ValueError(f"未找到用户 {user_id}")Error Handling
错误处理
Catch PyMySQL exceptions from :
pymysql.errpython
import pymysql.err
try:
with connection.cursor() as cursor:
cursor.execute(sql, args)
connection.commit()
except pymysql.err.IntegrityError as exc:
connection.rollback()
# duplicate key, foreign key violation, etc.
raise
except pymysql.err.OperationalError as exc:
# connection dropped, timeout, server gone away
raise
except pymysql.err.ProgrammingError as exc:
# bad SQL syntax, wrong number of params
raiseKey exception classes:
- — constraint violations (duplicate key, FK)
pymysql.err.IntegrityError - — connection / server errors
pymysql.err.OperationalError - — SQL syntax errors, wrong param count
pymysql.err.ProgrammingError - — invalid data for column type
pymysql.err.DataError - — base class for all DB errors
pymysql.err.DatabaseError
捕获中的PyMySQL异常:
pymysql.errpython
import pymysql.err
try:
with connection.cursor() as cursor:
cursor.execute(sql, args)
connection.commit()
except pymysql.err.IntegrityError as exc:
connection.rollback()
# 重复键、外键约束 violation 等
raise
except pymysql.err.OperationalError as exc:
# 连接断开、超时、服务器不可用
raise
except pymysql.err.ProgrammingError as exc:
# SQL语法错误、参数数量错误
raise关键异常类:
- — 约束 violation(重复键、外键)
pymysql.err.IntegrityError - — 连接/服务器错误
pymysql.err.OperationalError - — SQL语法错误、参数数量错误
pymysql.err.ProgrammingError - — 列类型数据无效
pymysql.err.DataError - — 所有数据库错误的基类
pymysql.err.DatabaseError
Connection Health Check
连接健康检查
Use to check liveness before executing queries in long-lived connections (e.g., background workers):
connection.ping(reconnect=True)python
connection.ping(reconnect=True)
with connection.cursor() as cursor:
cursor.execute(query)在长连接场景(如后台工作进程)中,执行查询前可使用检查连接活性:
connection.ping(reconnect=True)python
connection.ping(reconnect=True)
with connection.cursor() as cursor:
cursor.execute(query)Reading Config from my.cnf
my.cnf从my.cnf
读取配置
my.cnfAvoid hardcoding credentials. Use to read from a MySQL option file:
read_default_filepython
connection = pymysql.connect(
read_default_file="~/.my.cnf",
read_default_group="client",
database="mydb",
charset="utf8mb4",
cursorclass=pymysql.cursors.DictCursor,
)~/.my.cnfini
[client]
host = db.internal
user = app_user
password = secret避免硬编码凭据。使用从MySQL配置文件中读取:
read_default_filepython
connection = pymysql.connect(
read_default_file="~/.my.cnf",
read_default_group="client",
database="mydb",
charset="utf8mb4",
cursorclass=pymysql.cursors.DictCursor,
)~/.my.cnfini
[client]
host = db.internal
user = app_user
password = secretQuick Reference
快速参考
python
import pymysql
import pymysql.cursorspython
import pymysql
import pymysql.cursorsConnect
连接
conn = pymysql.connect(
host="localhost", user="u", password="p", database="db",
charset="utf8mb4", cursorclass=pymysql.cursors.DictCursor,
)
conn = pymysql.connect(
host="localhost", user="u", password="p", database="db",
charset="utf8mb4", cursorclass=pymysql.cursors.DictCursor,
)
Query
查询
with conn.cursor() as cur:
cur.execute("SELECT * FROM t WHERE id = %s", (1,))
row = cur.fetchone()
with conn.cursor() as cur:
cur.execute("SELECT * FROM t WHERE id = %s", (1,))
row = cur.fetchone()
Write + commit
写入并提交
with conn.cursor() as cur:
cur.execute("INSERT INTO t (col) VALUES (%s)", ("val",))
conn.commit()
with conn.cursor() as cur:
cur.execute("INSERT INTO t (col) VALUES (%s)", ("val",))
conn.commit()
Bulk insert
批量插入
with conn.cursor() as cur:
cur.executemany("INSERT INTO t (a, b) VALUES (%s, %s)", rows)
conn.commit()
conn.close()
undefinedwith conn.cursor() as cur:
cur.executemany("INSERT INTO t (a, b) VALUES (%s, %s)", rows)
conn.commit()
conn.close()
undefinedAdditional Resources
额外资源
For detailed patterns and advanced usage, consult:
- — Connection pooling, SSL/TLS configuration, timeout tuning,
references/connection-patterns.mdpatternsmy.cnf - — Cursor type selection, streaming large result sets, stored procedures,
references/cursor-guide.mddebuggingmogrify
如需了解详细模式和高级用法,请参考:
- — 连接池、SSL/TLS配置、超时调优、
references/connection-patterns.md模式my.cnf - — 游标类型选择、大型结果集流式处理、存储过程、
references/cursor-guide.md调试mogrify