Eu criei uma biblioteca em Python que contém funções para acessar um banco de dados. Esta é uma biblioteca de wrapper em torno de um banco de dados de aplicativos de terceiros, gravada devido ao fato de que o aplicativo de terceiros não oferece uma API decente. Agora, originalmente deixei cada função abrir uma conexão com o banco de dados pela duração da chamada de função, até que minha lógica de programa usasse chamadas aninhadas para as funções nas quais eu estaria chamando uma função específica alguns milhares de vezes. Isso não teve muito desempenho. A criação de perfil mostrou que a sobrecarga estava na configuração da conexão com o banco de dados - uma vez por chamada de função. Então, mudei a conexão aberta de dentro da (s) função (s) para o próprio módulo, para que a conexão com o banco de dados fosse aberta quando o módulo da biblioteca fosse importado. Isso me deu um desempenho aceitável.
Agora eu tenho duas perguntas sobre isso. Em primeiro lugar, preciso me preocupar com o fato de não estar mais fechando explicitamente a conexão com o banco de dados e como poderia fazê-lo explicitamente com essa configuração? Em segundo lugar, o que eu fiz cai perto do domínio das boas práticas e como eu poderia abordar isso de outra forma?
openConn
função e fazer o usuário passá-lo para cada função que eles chamam, de que maneira eles podem escopo a conexão em umawith
declaração ou qualquer outra coisaRespostas:
Realmente depende da biblioteca que você está usando. Alguns deles podem estar fechando a conexão por conta própria (Nota: verifiquei a biblioteca sqlite3 embutida, e não). O Python chamará um destruidor quando um objeto estiver fora do escopo, e essas bibliotecas podem implementar um destruidor que fecha as conexões normalmente.
No entanto, esse pode não ser o caso! Eu recomendaria, como outros têm nos comentários, envolvê-lo em um objeto.
Isso instancia sua conexão com o banco de dados no início e fechá-la quando o local em que seu objeto foi instanciado cai fora de escopo. Nota: Se você instanciar esse objeto no nível do módulo, ele persistirá para todo o aplicativo. A menos que isso seja planejado, sugiro separar as funções do banco de dados das funções que não são do banco de dados.
Felizmente, o python padronizou a API do banco de dados , portanto, isso funcionará com todos os bancos de dados compatíveis para você :)
fonte
self
emdef query(self,
?db.query('SELECT ...', var)
e ela se queixou de precisar de um terceiro argumento.MyDB
objeto primeiro:db = MyDB(); db.query('select...', var)
ResourceWarning: unclosed <socket.socket...
ao lidar com conexões com o banco de dados, há duas coisas com que se preocupar:
impedir instâncias de múltiplas conexões, deixar cada função abrir uma conexão com o banco de dados é considerado uma prática ruim, fornecendo o número limitado de sessões do banco de dados; você ficaria sem sessões; pelo menos, sua solução não seria expandida; em vez disso, use padrão singleton; sua classe seria instanciada apenas uma vez; para obter mais informações sobre esse padrão, consulte o link
fechando a conexão na saída do aplicativo, digamos que você não o fez, e que você tem pelo menos uma dúzia de instâncias do aplicativo executando o mesmo, no início tudo funcionaria bem, mas você ficaria sem sessões de banco de dados e a única correção seria reiniciar o servidor de banco de dados, o que não é uma coisa boa para um aplicativo ao vivo; portanto, use a mesma conexão sempre que possível.
para solidificar todos esses conceitos, veja o exemplo a seguir que envolve psycopg2
fonte
if Database._instance is None: NameError: name 'Database' is not defined
. Não consigo entender o queDatabase
é e como eu poderia consertar isso.Postgres.query(Postgres(), some_sql_query)
umwhile
loop, ele ainda abrirá e fechará a conexão em cada iteração ou a manterá aberta durante todo o tempo dowhile
loop até que o programa saia?query()
função, mas parece que há um problema com meu código quando executo meu aplicativo em "paralelo". Fiz uma pergunta separada a respeito: softwareengineering.stackexchange.com/questions/399582/…Seria interessante oferecer recursos de gerenciador de contexto para seus objetos. Isso significa que você pode escrever um código como este:
Isso oferecerá uma maneira prática de fechar a conexão com o banco de dados automaticamente chamando a classe usando a instrução with:
fonte
Muito tempo para pensar sobre isso. Hoje eu encontrei o caminho. Eu não sei, é o melhor caminho. você cria um arquivo com o nome: conn.py e o salva na pasta /usr/local/lib/python3.5/site-packages/conn/. Eu uso o freebsd e este é o caminho da minha pasta de pacotes de sites. no meu conn.py: conn = "dbname = usuário onívoro = senha do postgres = 12345678"
`` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` ` e no script que eu quero chamar de conexão, eu escrevo:
importar psycopg2 importar psycopg2.extras importar psycopg2.extensions
de conn import conn try: conn = psycopg2.connect (conn.conn), exceto: page = "Não é possível acessar o banco de dados"
cur = conn.cursor ()
e blá blá ....
espero que seja útil
fonte