Должен ли я вызывать connect () и close () для каждой транзакции Sqlite3?

#python #sqlite

#python #sqlite

Вопрос:

Я хочу написать модуль Python для абстрагирования транзакций базы данных для моего приложения. Мой вопрос в том, нужно ли мне вызывать connect() and close() для каждой транзакции? В коде:

 import sqlite3

# Can I put connect() here?
conn = sqlite3.connect('db.py')

def insert(args):
    # Or should I put it here?
    conn = sqlite3.connect('db.py')
    # Perform the transaction.
    c = conn.cursor()
    c.execute(''' insert args ''')
    conn.commit()
    # Do I close the connection here?
    conn.close()

# Or can I close the connection whenever the application restarts (ideally, very rarely)
conn.close()
 

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

Ответ №1:

Вы можете использовать одно и то же соединение повторно. Вы также можете использовать соединение (и курсор) в качестве диспетчера контекста, чтобы вам не нужно было явно вызывать close ни то, ни другое.

 def insert(conn, args):
    with conn.cursor() as c:
        c.execute(...)
    conn.commit()

with connect('db.py') as conn:
    insert(conn, ...)
    insert(conn, ...)
    insert(conn, ...)
 

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

Комментарии:

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

2. Если вы используете объект Connection в качестве выражения в with инструкции, он автоматически зафиксирует или откатит транзакции без необходимости включения conn.commit() . См. раздел Использование соединения в качестве диспетчера контекста

Ответ №2:

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

Используйте atexit модуль, если вы хотите убедиться, что закрытие в конечном итоге произойдет (даже если ваша программа завершается исключением). В частности, import atexit в начале вашей программы и atexit.register(conn.close) сразу после вас connect — обратите внимание, не () после close , вы хотите зарегистрировать функцию, которая будет вызываться в program exist (нормально или через исключение), а не для вызова функции.

К сожалению, если Python выйдет из строя, например, из-за ошибки в C-кодированном модуле, который Python не может перехватить, или a kill -9 и т. Д., Зарегистрированные функции выхода могут в конечном Итоге не вызываться. К счастью, в этом случае это не должно повредить в любом случае (кроме того, можно надеяться, что это редкое и экстремальное явление).