asyncpg数据库连接与操作指南
引言
asyncpg是一个高性能的Python异步PostgreSQL数据库客户端库,专为asyncio框架设计。相比传统的同步PostgreSQL驱动,asyncpg能够提供更好的并发性能,特别适合构建高性能的异步Web应用和服务。
基础使用
建立数据库连接
使用asyncpg的第一步是建立与PostgreSQL数据库的连接。这通过asyncpg.connect()
函数实现,该函数返回一个Connection
对象,用于执行查询和管理事务。
import asyncio
import asyncpg
import datetime
async def main():
# 建立到本地test数据库的连接
conn = await asyncpg.connect('postgresql://postgres@localhost/test')
# 创建用户表
await conn.execute('''
CREATE TABLE users(
id serial PRIMARY KEY,
name text,
dob date
)
''')
# 插入数据
await conn.execute('''
INSERT INTO users(name, dob) VALUES($1, $2)
''', 'Bob', datetime.date(1984, 3, 1))
# 查询数据
row = await conn.fetchrow('SELECT * FROM users WHERE name = $1', 'Bob')
print(row) # 输出查询结果
# 关闭连接
await conn.close()
asyncio.get_event_loop().run_until_complete(main())
注意:
- asyncpg使用PostgreSQL原生语法
$n
作为查询参数占位符 - 所有数据库操作都需要使用await关键字
- 操作完成后应显式关闭连接
类型转换
asyncpg自动处理PostgreSQL类型与Python类型之间的转换,支持所有标准数据类型,包括数组、复合类型、范围类型和枚举等。
主要类型对应关系
| PostgreSQL类型 | Python类型 | |---------------|------------| | bool | bool | | int, bigint | int | | float, double | float | | numeric | Decimal | | text, varchar | str | | date | date | | timestamp | datetime | | json, jsonb | str | | uuid | UUID | | array | list |
对于不支持的复杂类型,asyncpg允许自定义编解码器。
自定义类型转换
asyncpg提供了灵活的机制来处理自定义类型转换,通过set_type_codec()
和set_builtin_type_codec()
方法实现。
JSON自动转换示例
import json
async def setup_json_codec(conn):
await conn.set_type_codec(
'json',
encoder=json.dumps,
decoder=json.loads,
schema='pg_catalog'
)
复数类型转换示例
async def setup_complex_codec(conn):
await conn.execute('CREATE TYPE mycomplex AS (r float, i float)')
await conn.set_type_codec(
'complex',
encoder=lambda x: (x.real, x.imag),
decoder=lambda t: complex(t[0], t[1]),
format='tuple',
)
PostGIS几何类型转换
import shapely.geometry
import shapely.wkb
async def setup_geometry_codec(conn):
def encode_geometry(geom):
shape = shapely.geometry.shape(geom)
return shapely.wkb.dumps(shape)
def decode_geometry(wkb):
return shapely.wkb.loads(wkb)
await conn.set_type_codec(
'geometry',
encoder=encode_geometry,
decoder=decode_geometry,
format='binary',
)
事务管理
asyncpg提供了简单的事务管理接口,推荐使用async with
语法:
async with connection.transaction():
await connection.execute("INSERT INTO table VALUES(1, 2, 3)")
注意:不在显式事务块中的操作会立即提交(自动提交模式)。
连接池
对于高并发应用,建议使用连接池来管理数据库连接。asyncpg内置了高性能的连接池实现。
连接池使用示例
import asyncpg
from aiohttp import web
async def handle_request(request):
pool = request.app['pool']
async with pool.acquire() as conn:
async with conn.transaction():
result = await conn.fetchval('SELECT 2 ^ $1', 10)
return web.Response(text=f"Result: {result}")
async def init_db_pool(app):
app['pool'] = await asyncpg.create_pool(
database='postgres',
user='postgres',
min_size=5,
max_size=20
)
yield
await app['pool'].close()
连接池配置建议:
- 根据应用负载调整min_size和max_size
- 每个工作进程维护独立的连接池
- 长时间运行的操作应考虑使用专用连接
性能优化技巧
- 使用预编译语句:对于频繁执行的查询,使用
prepare()
方法预编译SQL语句 - 批量操作:使用
executemany()
进行批量插入 - 合理设置连接池大小:避免过小导致等待,过大浪费资源
- 监控连接使用:定期检查连接泄漏情况
总结
asyncpg提供了高性能的异步PostgreSQL数据库访问能力,通过合理使用连接池、事务管理和类型转换等功能,可以构建出高效可靠的数据库应用。本文介绍了asyncpg的核心功能和使用模式,帮助开发者快速上手并优化应用性能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考