我不确定我明白为什么 Django 不让我进行异步数据库事务

问题描述 投票:0回答:1

我正在尝试创建一个函数,一旦有人运行

!home
命令,它将在我的 django 用户模型中为我的不和谐机器人获取或创建用户记录 - 但我遇到了一个问题(据我所知) django 现有模型的正常部分,其中它不允许异步数据库事务。

我尝试使用内置的sync_to_async方法,但它引发了类似的问题。我可以在我的设置文件中更改某些内容,或者我无法在网上找到可以在这里实现此功能的内容吗?

这是我的 home 命令,由命令调用:

@bot.command(name="home", description="Displays the character sheet of your character in Oblivion After you have already created your guy")
async def home_async(ctx):
    user_instance, created = await sync_to_async(User.objects.get_or_create(
        discord_id=discord_user_id,
        defaults={'username': ctx.author.name}
    ))

    if created:
        character = Character.objects.create(name=f"New Character for {ctx.author.name}")
        user_instance.character = character
        user_instance.save()

    view = HomePageView(user=user_instance)
    await ctx.send(f"Welcome {ctx.author.display_name}! Manage your character and inventory here.", view=view)

目前这是我遇到此错误的问题:

Traceback (most recent call last):
  File "/mnt/m/ZocPy/OblivionAlchemy/OblivionAlchemy/venv/oblivion/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 1350, in invoke
    await ctx.command.invoke(ctx)
  File "/mnt/m/ZocPy/OblivionAlchemy/OblivionAlchemy/venv/oblivion/lib/python3.10/site-packages/discord/ext/commands/core.py", line 1029, in invoke
    await injected(*ctx.args, **ctx.kwargs)  # type: ignore
  File "/mnt/m/ZocPy/OblivionAlchemy/OblivionAlchemy/venv/oblivion/lib/python3.10/site-packages/discord/ext/commands/core.py", line 244, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async
python django
1个回答
0
投票

SynchronousOnlyOperation:你不能从异步上下文中调用它基本上表明你正在尝试在异步上下文中执行同步数据库操作,这在Django中是不允许的。

使用Django的sync_to_async装饰器将同步数据库调用转换为异步调用。用sync_to_async包装User.objects.get_or_create,您将能够在异步命令函数中异步执行数据库操作。

from asgiref.sync import sync_to_async

@bot.command(name="home", description="Displays the character sheet of your character in Oblivion After you have already created your guy")
async def home_async(ctx):
    user_instance, created = await sync_to_async(User.objects.get_or_create)(
        discord_id=discord_user_id,
        defaults={'username': ctx.author.name}
    )

    if created:
        character = Character.objects.create(name=f"New Character for {ctx.author.name}")
        user_instance.character = character
        user_instance.save()

    view = HomePageView(user=user_instance)
    await ctx.send(f"Welcome {ctx.author.display_name}! Manage your character and inventory here.", view=view)
© www.soinside.com 2019 - 2024. All rights reserved.