page contents

Python异步数据库asyncpg:PostgreSQL的高性能异步数据访问编程接口

刚开始做异步项目的时候 我简直要疯了。用psycopg2写的代码在FastAPI里跑起来就是卡顿 几百个并发请求过来 数据库连接直接爆满。那会儿我还不知道有asyncpg这个神器。

attachments-2025-07-UJAKzHf2686b212da8d4e.jpg刚开始做异步项目的时候 我简直要疯了。用psycopg2写的代码在FastAPI里跑起来就是卡顿 几百个并发请求过来 数据库连接直接爆满。那会儿我还不知道有asyncpg这个神器。

01

传统的psycopg2是同步的嘛。每次数据库操作都要等待 线程被阻塞了 整个应用的吞吐量自然上不去。我记得有一次压测 QPS才200多 老板脸都绿了。

后来同事推荐了asyncpg。说这货专门为PostgreSQL设计 性能比psycopg2快好几倍呢。

一开始我还半信半疑。

安装很简单 pip install asyncpg就完事了。第一次用的时候真的被震撼到了 同样的查询操作 响应时间直接砍了一半。

import asyncio

import asyncpg

async def connect_db():

    # 创建数据库连接 比psycopg2简洁多了

    conn = await asyncpg.connect(

        host='localhost',

        database='testdb', 

        user='postgres',

        password='password'

    )

    return conn


async def fetch_users(conn):

    # 异步查询用户数据 再也不会阻塞了

    rows = await conn.fetch('SELECT id name email FROM users LIMIT 10')

    for row in rows:

        print(f"用户ID: {row['id']} 姓名: {row['name']}")

    

async def main():

    conn = await connect_db()

    await fetch_users(conn)

    await conn.close()


# 运行异步函数

asyncio.run(main())代码看起来清爽多了对吧。

02

连接池这块儿更是让我眼前一亮。以前用psycopg2的时候 要自己管理连接池 各种配置参数搞得头大。asyncpg的连接池超级智能 自动管理连接的创建和回收。

import asyncpg


async def create_pool():

    # 创建连接池 最大20个连接

    pool = await asyncpg.create_pool(

        host='localhost',

        database='testdb',

        user='postgres', 

        password='password',

        min_size=5,     # 最小连接数

        max_size=20,    # 最大连接数

        command_timeout=60

    )

    return pool


async def batch_insert(pool, data_list):

    # 批量插入数据 效率贼高

    async with pool.acquire() as conn:

        await conn.executemany(

            'INSERT INTO users (name email) VALUES ($1 $2)',

            data_list

        )


# 实际使用

pool = await create_pool()

users_data = [('张三', 'zhang@email.com'), ('李四', 'li@email.com')]

await batch_insert(pool, users_data)性能提升太明显了。

以前插入1000条数据要3秒多 现在800毫秒就搞定。批量操作的executemany方法特别给力 比循环执行execute快了不知道多少倍。

03

说到踩坑经验呢。

第一个坑就是参数占位符。asyncpg用的是2这种格式 不是psycopg2的%s。刚开始我老是写错 程序各种报错。

还有就是事务处理。asyncpg的事务管理比较严格 必须显式提交或者回滚。

async def transfer_money(pool, from_user, to_user, amount):

    async with pool.acquire() as conn:

        # 开启事务 这一步很关键

        async with conn.transaction():

            try:

                # 扣款操作

                   await conn.execute(

                    'UPDATE accounts SET balance = balance - $1 WHERE user_id = $2',

                    amount, from_user

                )

                

                # 加款操作  

                await conn.execute(

                    'UPDATE accounts SET balance = balance + $1 WHERE user_id = $2', 

                    amount, to_user

                )

                

                print("转账成功了")

            except Exception as e:

                # 异常会自动回滚

                print(f"转账失败: {e}")

                raise这个事务写法挺优雅的吧。

04

性能对比的数据我记得很清楚。在我们的生产环境里 同样的业务逻辑下 asyncpg比psycopg2的QPS提升了3倍多。内存占用也少了不少。

特别是在高并发场景下 差距更明显。1000个并发请求 psycopg2基本扛不住 asyncpg还能稳定运行。

不过也有一些局限性啦。

asyncpg只支持PostgreSQL 如果你用MySQL或者其他数据库就没办法了。还有就是学习成本 需要对异步编程有一定了解。

05

现在我基本上所有的新项目都用asyncpg了。配合FastAPI或者aiohttp 整个技术栈都是异步的 性能提升非常显著。

建议大家在选择的时候 如果项目对性能要求比较高 并且用的是PostgreSQL 那asyncpg绝对是首选。如果只是普通的CRUD操作 数据量不大 用psycopg2也够了。

最后提醒一点 记得合理配置连接池的大小。太小了影响并发 太大了浪费资源 一般根据服务器配置和业务需求来调整就行。

总的来说 asyncpg确实是个好东西 值得每个Python开发者了解一下。特别是做Web后端的朋友们 用了就回不去了。

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

  • 发表于 2025-07-07 09:21
  • 阅读 ( 40 )
  • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
小柒
小柒

2172 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 2172 文章
  3. Pack 1335 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章