You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Aiogram 3.7b开发Telegram Bot遇SyncToAsync协程未等待错误

问题分析与解决方案

问题根源

报错的核心原因是get_parents_student_keyboard函数的分支返回值不符合预期:
当学生数量为1时,代码直接返回get_date_chooser_parents(tg_bot_auth)的调用结果。如果get_date_chooser_parents是被@sync_to_async装饰的异步函数,这个调用会返回协程对象,而非预期的(keyboard_markup, text, state_next)三元组。
当get_parents_student_keyboard(被@sync_to_async包装的同步函数)返回该协程对象时,handler中await后得到的仍然是协程对象,无法解包为三个变量,因此触发TypeError;同时协程未被正确执行,引发RuntimeWarning。

解决方案

根据get_date_chooser_parents的类型选择对应修改方式:

方案1:get_date_chooser_parents为同步函数

确保get_date_chooser_parents未被@sync_to_async装饰,直接返回(键盘标记, 文本, 状态)三元组。此时get_parents_student_keyboard的代码无需修改,调用后会正常返回符合要求的三元组。

方案2:get_date_chooser_parents为异步函数

将get_parents_student_keyboard改为异步函数,移除@sync_to_async装饰器,内部通过await获取get_date_chooser_parents的返回值,同时同步ORM操作改为异步方式:

async def get_parents_student_keyboard(tg_bot_auth: TGBotAuth):
    parent = await tg_bot_auth.user.aget()  # 异步关联查询
    students = await Student.objects.filter(parent=parent).all()
    builder = ReplyKeyboardBuilder()
    if len(students) == 1:
        # await异步函数,获取正确的三元组返回值
        return await get_date_chooser_parents(tg_bot_auth)
    for student in students:
        builder.button(text=str(student))
    return builder.as_markup(), MESSAGES['parents_students'], ParentsState.student_choosing

handler中的调用保持await get_parents_student_keyboard(tg_bot_auth)不变即可。

额外注意事项

  • 使用Django ORM时,异步函数内必须用异步查询方法(如aget()、all().await()),不能直接使用同步查询语法。
  • 确保函数所有分支都返回三元组,避免返回其他类型对象导致解包失败。

内容的提问来源于stack exchange,提问作者Shuhrat Azimuratov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 04:06:01