#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
и т. Д., Зарегистрированные функции выхода могут в конечном Итоге не вызываться. К счастью, в этом случае это не должно повредить в любом случае (кроме того, можно надеяться, что это редкое и экстремальное явление).