Я не уверен, что понимаю, почему Django не позволяет мне выполнять асинхронные транзакции с базой данных

Я пытаюсь создать функцию, которая будет получать_или_создавать запись пользователя для моего бота discord в моей модели django User, как только кто-то выполнит команду !home - но я столкнулся с проблемой, которая (насколько я понимаю) является нормальной частью существующей модели django, в которой запрещены асинхронные транзакции с базой данных.

Я пробовал использовать встроенный метод 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)

В настоящее время я сталкиваюсь с этой ошибкой:

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

SynchronousOnlyOperation: You cannot call this from an async context в основном говорит о том, что вы пытаетесь выполнить синхронную операцию с базой данных в асинхронном контексте, что вроде как не разрешено в Django.

используйте декоратор Django sync_to_async для преобразования синхронных вызовов базы данных в асинхронные. оберните User.objects.get_or_create с 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)
Вернуться на верх