
`asyncpg.connect()` 返回的是一个协程对象,必须用 `await` 等待其完成才能获得真正的 `connection` 实例;否则直接调用 `.execute()` 会报错“coroutine object has no attribute 'execute'”。
在使用 asyncpg 进行异步 PostgreSQL 操作时,一个常见误区是混淆了协程函数调用与实际连接对象。你代码中的核心问题在于:
conn = asyncpg.connect(...) # ❌ 错误:这只是创建了一个协程对象,未执行!
这行代码并未真正建立数据库连接,而只是返回了一个 coroutine 对象。后续若尝试 conn.execute(...),Python 会提示:
AttributeError: 'coroutine' object has no attribute 'execute'
✅ 正确做法是显式 await 该协程,获取真正的 asyncpg.Connection 实例:
conn = await asyncpg.connect("postgresql://postgres@localhost/user")此外,你的路由处理逻辑还存在多个关键问题,需一并修正:
✅ 完整修复示例(含最佳实践)
import asyncpg
from aiogram import Router
from aiogram.types import Message
from data.config import Config
Data_base = Router()
# ✅ 推荐:封装连接为工具函数,并确保正确 await
async def get_db_connection():
return await asyncpg.connect("postgresql://postgres@localhost/user")
@Data_base.message()
async def including_data_from_user(message: Message):
try:
# ✅ 正确获取连接(await 协程)
conn = await get_db_connection()
# ✅ 使用 $1, $2 等占位符防止 SQL 注入(强烈推荐!)
await conn.execute(
"""
INSERT INTO "user" (first_name, last_name, age, telegram_id)
VALUES ($1, $2, $3, $4)
""",
message.from_user.first_name,
message.from_user.last_name,
1,
message.from_user.id
)
await message.answer("✅ 用户数据已成功写入数据库!")
except Exception as e:
await message.answer(f"❌ 数据库操作失败:{e}")
finally:
# ✅ 务必关闭连接(或使用连接池更佳)
if 'conn' in locals() and conn:
await conn.close()⚠️ 关键注意事项
- 永远不要拼接 SQL 字符串:你原代码中 f'''INSERT ... {message.from_user.first_name}''' 极易导致 SQL 注入。务必使用 $1, $2 占位符 + 参数化查询。
- 表名 user 是 PostgreSQL 保留关键字:建议用双引号包裹 "user",或重命名表(如 users)。
- 避免重复创建连接:高频场景应使用 asyncpg.create_pool() 创建连接池,而非每次 connect()。
- 资源清理不可少:conn.close() 应放在 finally 块中,或使用 async with conn.transaction(): 上下文管理。
遵循以上修正,即可彻底解决 'coroutine' object has no attribute 'execute' 错误,并构建健壮、安全的异步数据库交互逻辑。










