Я создал библиотеку в Python, которая содержит функции для доступа к базе данных. Это библиотека-обертка вокруг базы данных сторонних приложений, написанная из-за того, что стороннее приложение не предлагает достойного API. Теперь я изначально позволял каждой функции открывать соединение с базой данных на время вызова функции, что было в порядке, пока моя программная логика не использовала вложенные вызовы функций, где я бы затем вызывал определенную функцию несколько тысяч раз. Это было не очень эффективно. Профилирование показало, что накладные расходы были при настройке соединения с базой данных - один раз на вызов функции. Поэтому я переместил открытое соединение из функции (ей) в сам модуль, чтобы соединение с базой данных было открыто при импорте библиотечного модуля. Это дало мне приемлемую производительность.
Теперь у меня есть два вопроса по этому поводу. Во-первых, нужно ли мне беспокоиться о том, что я больше не закрываю соединение с базой данных явно, и как я могу сделать это явно с этой настройкой? Во-вторых, относится ли то, что я сделал, к сфере хорошей практики, и как я мог бы иначе подойти к этому?
openConn
функцию и сделайте так, чтобы пользователь передавал ее каждой вызываемой функции таким образом, чтобы они могли охватывать соединение вwith
выражении или чем-то ещеОтветы:
Это действительно зависит от используемой вами библиотеки. Некоторые из них могут закрывать соединение самостоятельно (Примечание: я проверил встроенную библиотеку sqlite3, но это не так). Python будет вызывать деструктор, когда объект выходит из области видимости, и эти библиотеки могут реализовывать деструктор, который изящно закрывает соединения.
Однако это может быть не так! Я бы порекомендовал, как и другие в комментариях, обернуть его в объект.
Это создаст экземпляр вашего подключения к базе данных в начале и закроет его, когда место, где был создан ваш объект, выйдет из области видимости. Примечание. Если вы создадите экземпляр этого объекта на уровне модуля, он сохранится для всего вашего приложения. Если это не предусмотрено, я бы предложил отделить функции базы данных от функций, не связанных с базой данных.
К счастью, python стандартизировал API базы данных , поэтому он будет работать со всеми совместимыми БД для вас :)
источник
self
вdef query(self,
?db.query('SELECT ...', var)
и он жаловался на необходимость третьего аргумента.MyDB
объекта:db = MyDB(); db.query('select...', var)
ResourceWarning: unclosed <socket.socket...
при обработке соединений с базой данных необходимо учитывать две вещи:
предотвратить множественные экземпляры соединений, позволяя каждой функции открывать соединение с базой данных считается плохой практикой, поскольку ограниченное количество сеансов базы данных может привести к исчерпанию сеансов; по крайней мере, ваше решение не будет масштабироваться, вместо этого используйте шаблон singleton, ваш класс будет создан только один раз, для получения дополнительной информации об этом шаблоне см. ссылку
закрытие соединения при выходе из приложения, допустим, что вы этого не сделали, и что у вас есть по крайней мере дюжина экземпляров приложения, выполняющего то же самое, сначала все будет хорошо, но у вас закончатся сеансы базы данных, и единственное исправление было бы перезапустить сервер базы данных, что не очень хорошо для живого приложения, поэтому, когда это возможно, используйте одно и то же соединение.
Чтобы закрепить все эти понятия, посмотрите следующий пример, который включает в себя psycopg2
источник
if Database._instance is None: NameError: name 'Database' is not defined
. Я не могу понять, чтоDatabase
и как я мог это исправить.Postgres.query(Postgres(), some_sql_query)
вwhile
цикле, будет ли еще открыть и закрыть соединение в каждой итерации, или держать его открытым в течение всего времениwhile
цикла до выхода из программы?query()
функции, но, кажется, есть проблема с моим кодом, когда я запускаю свое приложение «параллельно». Я сделал отдельный вопрос об этом: softwareengineering.stackexchange.com/questions/399582/…Было бы интересно предложить возможности менеджера контекста для ваших объектов. Это означает, что вы можете написать такой код:
Это предложит вам удобный способ автоматически закрыть соединение с базой данных, вызвав класс с помощью оператора with:
источник
Долго думать об этом. Сегодня я нашел способ. я не знаю, что это лучший способ. вы создаете файл с именем: conn.py и сохраняете его в /usr/local/lib/python3.5/site-packages/conn/ папке. Я использую freebsd, и это путь к моей папке site-packages. в моем conn.py: conn = "имя_бдома = всеядный пользователь = пароль postgres = 12345678"
`` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` и в сценарии я хочу вызвать соединение, я пишу:
импорт psycopg2 импорт psycopg2.extras импорт psycopg2.extensions
из conn import conn try: conn = psycopg2.connect (conn.conn) за исключением: page = "Нет доступа к базе данных"
cur = conn.cursor ()
и бла-бла ....
я надеюсь, что это полезно
источник