PyMySQL与asyncpg:同步/异步MySQL和PostgreSQL驱动
请对比PyMySQL(同步MySQL驱动)和asyncpg(异步PostgreSQL驱动)的用法和性能特点。说明连接池配置(pymysql.pool vs asyncpg.create_pool)、参数化查询防止SQL注入、以及事务处理的区别。为什么asyncpg比psycopg2快?给出使用asyncpg进行批量插入和流式查询的示例。
回答
专业代码师
PyMySQL(同步MySQL):
import pymysql
from pymysqlpool.pool import Pool
pool = Pool(host='localhost', user='root', password='pass', db='test', max_size=10)
with pool.get_conn() as conn:
with conn.cursor() as cur:
cur.execute('SELECT * FROM users WHERE age > %s', (18,)) # 参数化查询
rows = cur.fetchall()
asyncpg(异步PostgreSQL):
import asyncpg
async def main():
pool = await asyncpg.create_pool(dsn='postgresql://user:pass@localhost/db', min_size=5, max_size=20)
async with pool.acquire() as conn:
# 参数化查询
rows = await conn.fetch('SELECT * FROM users WHERE age > $1', 18)
# 批量插入
await conn.executemany('INSERT INTO users(name, age) VALUES($1, $2)',
[('Alice', 25), ('Bob', 30)])
# 流式查询(内存友好)
async for record in conn.cursor('SELECT * FROM large_table'):
process(record)
await main()
asyncpg性能优势(比psycopg2快2-3x):
- 纯C实现的协议解析(asyncio事件循环中无GIL阻塞)
- 零拷贝结果解码
- 预编译查询(PREPARE)缓存
| 特性 | PyMySQL | asyncpg |
|---|---|---|
| 数据库 | MySQL | PostgreSQL |
| 模型 | 同步 | 异步 |
| 连接池 | pymysqlpool/DBUtils | 内建create_pool |
| 参数绑定 | %s | $1, $2 |
| 协议解析 | Python | C |
SQL注入防护:永远使用参数化查询(%s或$1),不要拼接SQL字符串。