C
C
cheems_crying2020-07-07 17:14:50
Python
cheems_crying, 2020-07-07 17:14:50

How to fix the fact that await does not work and the code is executed further without data from the DB?

qq all, there is a problem, when executing the code, await does not work and the code is executed further without data from the database, who can tell me how to fix it?

The code itself:

import asyncio
import os
import threading
import discord
from allauth.socialaccount.models import SocialAccount
from asgiref.sync import sync_to_async
from channels.db import database_sync_to_async

from main.models import Game, Purchase, Key


def start():
thread = threading.Timer(0, ds)
thread.daemon = True
thread.start()


def ds():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
client = discord.Client()

@client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))

@client.event
async def on_message(message):
if message.author == client.user:
return

if message.content.startswith('$hello'):
game = await sync_to_async(lambda: Game.objects.all()[0], thread_sensitive=True)()
await message.channel.send(game.name)

@client.event
async def on_member_join(member):
allAccounts = await sync_to_async(lambda: SocialAccount.objects.all(), thread_sensitive=True)()
for acc in allAccounts:
if acc.extra_data['id'] == str(member.id):
account_id = acc.extra_data['id']
purchases = await sync_to_async(lambda: Key.objects.filter(user__id=account_id), thread_sensitive=True)()
keys = [await sync_to_async(lambda: Key.objects.filter(purchase__id=purchase.id), thread_sensitive=True)() for purchase in purchases]
for key in keys:
role = discord.utils.get(member.guild.roles, id=key.cheat.ds_role_id)
print(str(key.cheat.ds_role_id))
await member.add_roles(role)
break


@client.event
async def on_error(event, *args, **kwargs):
client.run(os.environ.get('DS_BOT_TOKEN'))

client.run(os.environ.get('DS_BOT_TOKEN'))

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Maxim Nevzorov, 2020-07-08
@cheems_crying

Executing Synchronous Code in Thread or Process Pools
As import this:

Simple is better than complex.

I just do not see the point in all these sync_to_asyncand others.
database_sync_to_asyncnot used at all in this code.
Use the discord.py extension called "commands". It comes with the library and greatly simplifies life when writing commands.
Errors should never pass silently.
Unless explicitly silenced.

Reconnecting the bot on any error sounds like a VERY bad idea.
import asyncio
import os
from functools import partial

import discord
from discord.ext import commands
from allauth.socialaccount.models import SocialAccount

from main.models import Game, Purchase, Key


bot = commands.Bot()


@bot.event
async def on_ready():
    print('We have logged in as {0.user}'.format(bot))

@commands.command()
async def hello(ctx):
    game = (await bot.loop.run_in_executor(None, Game.objects.all))[0]
    await ctx.send(game.name)

@bot.event
async def on_member_join(member):
    allAccounts = await bot.loop.run_in_executor(None, SocialAccount.objects.all)
    for acc in allAccounts:
        if acc.extra_data['id'] == str(member.id):
            account_id = acc.extra_data['id']
            purchases = await bot.loop.run_in_executor(None, partial(Key.objects.filter, user__id=account_id))
            keys = [await bot.loop.run_in_executor(None, partial(Key.objects.filter, purchase__id=purchase.id)) for purchase in purchases]
    for key in keys:
        role = discord.utils.get(member.guild.roles, id=key.cheat.ds_role_id)
        print(str(key.cheat.ds_role_id))
        await member.add_roles(role)
        break


bot.run(os.environ.get('DS_BOT_TOKEN'))

Maybe this code will help you. It was written without taking into account the contents of SocialAccount and main.models, so the code affecting them remained approximately unchanged.
The indents were also guessed purely from the code.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question