Search code examples
pythonpostgresqldiscord.pyasyncpg

Asyncpg INSERT query for timestamp returns ERROR syntax error at or near "18"


Hi I'm getting an error that occurs when trying to add the timestamp. I keep getting the error asyncpg.exceptions.PostgresSyntaxError: syntax error at or near "18" and this line end_date = duration + dt.datetime.now(bst) # timestamp seems to be the culprit however I'm unsure why this is the case.

Here is what I'm working with:

    if time is not None:
        conn = await asyncpg.connect(DATABASE_URL)
        async with conn.transaction():
            await conn.fetch(f"SELECT time FROM blacklist WHERE username={member.id}")
        
            duration = find_date(time)
            bst = pytz.timezone('Europe/London')
            end_date = duration + dt.datetime.now(bst) # timestamp
            fmt_date = end_date.strftime("%#d %b %Y, at %I:%M%p")
            await conn.fetch(f"UPDATE blacklist SET time={end_date} WHERE username={member.id}")
        
            await member.add_roles(restricted, reason=f'Restricted role added by {author.name}')
            await member.remove_roles(members)
            
            await conn.close()

            msg = f"{member} has been restricted until {fmt_date}."
            embed = discord.Embed(title="Restricted", description=msg, colour=author.color)
            await ctx.send(embed=embed)
            return

Solution

  • You don't pass the arguments in f-strings when dealing with SQL queries, the syntax for query arguments in asyncpg is $n, also I see that you're using the Connection.fetch method but you're simply updating the table, I'd suggest you to use Connection.execute

    Your code fixed:

    end_date = # Should be a datetime.datetime instance
    await conn.execute("""
        UPDATE blacklist 
        SET time = $1 
        WHERE username = $2
    """, end_date, member.id)
    

    Removing timezone awareness

    end_date = # `datetime.datetime` instance
    naive = end_date.replace(tzinfo=None)
    await conn.execute("""
        UPDATE blacklist 
        SET time = $1 
        WHERE username = $2
    """, naive, member.id)
    

    References:

    PS: Don't create a new connection everytime you want to use it, normal practice is to have one long-term database connection