|
import asyncio |
|
|
|
import asqlite |
|
|
|
|
|
async def shared_connection(): |
|
""" |
|
Expected result: |
|
Guild and relevant members both exist or neither exist. |
|
|
|
Actual result: |
|
Guild is deleted, but members still exist for some time. |
|
|
|
Output: |
|
Deleting guild and members... |
|
guilds = [] |
|
members = [(1, 5), (1, 6), (1, 7)] |
|
Done deleting guild and members. |
|
guilds = [] |
|
members = [] |
|
|
|
Solution: |
|
Connect in each function where you need a connection. |
|
|
|
Fixed output: |
|
Deleting guild and members... |
|
guilds = [(1,)] |
|
members = [(1, 5), (1, 6), (1, 7)] |
|
Done deleting guild and members. |
|
guilds = [] |
|
members = [] |
|
""" |
|
conn = await asqlite.connect(":memory:") |
|
conn._conn.row_factory = None # hack just for example output, don't do this |
|
|
|
# a real DB should use foreign keys, this is just for example |
|
await conn.execute("CREATE TABLE guilds (guild_id INT)") |
|
await conn.execute("CREATE TABLE members (guild_id INT, user_id INT)") |
|
|
|
await conn.execute("INSERT INTO guilds VALUES (?)", (1,)) |
|
await conn.executemany( |
|
"INSERT INTO members VALUES (?, ?)", ((1, 5), (1, 6), (1, 7)) |
|
) |
|
|
|
async def command_one(): |
|
print("Deleting guild and members...") |
|
await conn.execute("DELETE FROM guilds WHERE guild_id = ?", (1,)) |
|
# this sleep is to reliably reproduce the example |
|
# normal bot things outside your control would cause the same issue |
|
await asyncio.sleep(0.5) |
|
await conn.execute("DELETE FROM members WHERE guild_id = ?", (1,)) |
|
await conn.commit() |
|
print("Done deleting guild and members.") |
|
|
|
async def command_two(): |
|
... # do something unrelated that you need to commit |
|
await conn.commit() |
|
cur = await conn.execute("SELECT * FROM guilds") |
|
guilds = await cur.fetchall() |
|
cur = await conn.execute("SELECT * FROM members") |
|
members = await cur.fetchall() |
|
print(f"{guilds = }\n{members = }") |
|
|
|
await asyncio.wait({asyncio.create_task(command_one()), |
|
asyncio.create_task(command_two())}) |
|
await command_two() |
|
|
|
|
|
asyncio.run(shared_connection()) |