повторное использование aiosqlite соединения - PullRequest
0 голосов
/ 24 декабря 2018

Я просто не могу понять, как использовать модуль aiosqlite, чтобы я мог сохранить соединение для дальнейшего использования.

Пример, основанный на странице проекта aiosqlite

async with aiosqlite.connect('file.db') as conn:
    cursor = await conn.execute("SELECT 42;")
    rows = await cursor.fetchall()
    print('rows %s' % rows)

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

Как правило, с помощью sqlite я открываю соединение, сжимаю его и затем используюэто на протяжении всей жизни программы.

Я также пробовал такие вещи, как:

conn = aiosqlite.connect('file.db')
c = await conn.__enter__()
AttributeError: 'Connection' object has no attribute '__enter__'

Есть ли способ использовать этот модуль без менеджера контекста?

1 Ответ

0 голосов
/ 28 декабря 2018

«Наилучшим» способом было бы для точки входа вашего приложения создать соединение aiosqlite с помощью метода менеджера контекста, сохранить ссылку на объект соединения где-нибудь, а затем запустить метод «цикла выполнения» приложения изнутриэтот контекст.Это гарантирует, что при выходе из приложения соединение sqlite будет очищено надлежащим образом.Это может выглядеть примерно так:

async def main():
    async with aiosqlite.connect(...) as conn:
        # save conn somewhere
        await run_loop()

С другой стороны, вы можете ожидать соответствующие методы ввода / вывода:

try:
    conn = aiosqlite.connect(...)
    await conn.__aenter__()
    # do stuff
finally:
    await conn.__aexit__()

Независимо от того, имейте в виду, что асинхронная природа aiosqlite действительно означает, чтообщие подключения могут привести к перекрытию транзакций.Если вам нужна уверенность в том, что параллельные запросы выполняются с отдельными транзакциями, вам потребуется отдельное соединение для каждой транзакции.

В соответствии с Документами Python sqlite об общем подключении:

При использовании нескольких потоков с одним и тем же соединением пользователь должен сериализовать операции записи во избежание повреждения данных.

Это в равной степени относится к aiosqlite и asyncio.Например, следующий код потенциально может перекрывать обе вставки в одной транзакции:

async def one(db):
    await db.execute("insert ...")
    await db.commit()

async def two(db):
    await db.execute("insert ...")
    await db.commit()

async def main():
    async with aiosqlite.connect(...) as db:
        await asyncio.gather(one(db), two(db))

Правильным решением здесь будет либо создать соединение для каждой транзакции, либо использовать что-то вроде executescript для выполнениявся транзакция сразу.

...