Я не уверен, что понимаю, почему 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)