He creado una biblioteca en Python que contiene funciones para acceder a una base de datos. Esta es una biblioteca de contenedor alrededor de una base de datos de aplicaciones de terceros, escrita debido al hecho de que la aplicación de terceros no ofrece una API decente. Ahora originalmente dejé que cada función abriera una conexión de base de datos durante la duración de la llamada a la función, lo cual estuvo bien, hasta que la lógica de mi programa usó llamadas anidadas a las funciones donde luego llamaría a una función en particular unas pocas miles de veces. Esto no fue muy eficiente. El perfil de esto mostró que la sobrecarga estaba en la configuración de la conexión de la base de datos, una vez por llamada a la función. Así que moví la conexión abierta desde dentro de las funciones al módulo en sí, para que la conexión de la base de datos se abriera cuando se importó el módulo de la biblioteca. Esto me dio un rendimiento aceptable.
Ahora tengo dos preguntas con respecto a esto. En primer lugar, ¿debo preocuparme de que ya no cierre explícitamente la conexión de la base de datos y cómo podría hacerlo explícitamente con esta configuración? En segundo lugar, ¿lo que he hecho se acerca al ámbito de las buenas prácticas y cómo podría abordar esto?
openConn
función y haga que el usuario la pase a cada función que llame, de esa manera puede ver la conexión en unawith
declaración o lo que seaRespuestas:
Realmente depende de la biblioteca que estés usando. Algunos de ellos podrían estar cerrando la conexión por su cuenta (Nota: Revisé la biblioteca sqlite3 incorporada, y no lo hace). Python llamará a un destructor cuando un objeto salga del alcance, y estas bibliotecas podrían implementar un destructor que cierre las conexiones con gracia.
Sin embargo, ¡ese podría no ser el caso! Recomendaría, como lo han hecho otros en los comentarios, envolverlo en un objeto.
Esto creará una instancia de la conexión de su base de datos al principio y la cerrará cuando el lugar donde se creó la instancia de su objeto quede fuera de alcance. Nota: Si crea una instancia de este objeto a nivel de módulo, persistirá para toda su aplicación. A menos que esto se pretenda, sugeriría separar las funciones de su base de datos de las funciones que no son de la base de datos.
Afortunadamente, python ha estandarizado la API de la base de datos , por lo que funcionará con todas las bases de datos compatibles para usted :)
fuente
self
endef query(self,
?db.query('SELECT ...', var)
y se quejó de necesitar un tercer argumento.MyDB
objeto:db = MyDB(); db.query('select...', var)
ResourceWarning: unclosed <socket.socket...
Al manejar las conexiones de la base de datos, hay dos cosas que deben preocuparse:
evitar múltiples instancias de conexiones, dejar que cada función abra una conexión de base de datos se considera una mala práctica, dado el número limitado de sesiones de base de datos, se quedaría sin sesiones; al menos su solución no se escalaría, en su lugar, use un patrón singleton, su clase se instanciaría solo una vez, para obtener más información sobre este patrón, consulte el enlace
cerrando la conexión al salir de la aplicación, digamos que no, y que tiene al menos una docena de instancias de la aplicación ejecutándose haciendo lo mismo, al principio todo saldría bien, pero se quedaría sin sesiones de la base de datos, y la única solución sería reiniciar el servidor de la base de datos, lo que no es bueno para una aplicación en vivo, por lo tanto, use la misma conexión siempre que sea posible.
Para solidificar todos estos conceptos, vea el siguiente ejemplo que envuelve psycopg2
fuente
if Database._instance is None: NameError: name 'Database' is not defined
. No puedo entender quéDatabase
es y cómo podría solucionarlo.Postgres.query(Postgres(), some_sql_query)
a unwhile
ciclo, ¿se abriría y cerraría la conexión en cada iteración, o lo mantendría abierto durante todo elwhile
ciclo hasta que el programa salga?query()
función, pero parece que hay un problema con mi código cuando ejecuto mi aplicación en "paralelo". Hice una pregunta por separado al respecto: softwareengineering.stackexchange.com/questions/399582/…Sería interesante ofrecer capacidades de administrador de contexto para sus objetos. Esto significa que puede escribir un código como este:
Esto le ofrecerá una forma práctica de cerrar la conexión a la base de datos automáticamente llamando a la clase usando la instrucción with:
fuente
Mucho tiempo para pensar en esto. A día, encontré el camino. No sé, es la mejor manera. crea un archivo con el nombre: conn.py y lo guarda en la carpeta /usr/local/lib/python3.5/site-packages/conn/. Yo uso freebsd y esta es la ruta de mi carpeta de paquetes de sitio. en mi conn.py: conn = "nombrebd = usuario omnívoro = contraseña de postgres = 12345678"
`` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` y en el script que quiero llamar a la conexión, escribo:
import psycopg2 import psycopg2.extras import psycopg2.extensions
from conn import conn try: conn = psycopg2.connect (conn.conn) excepto: page = "No se puede acceder a la base de datos"
cur = conn.cursor ()
y bla, bla ...
espero que esto sea útil
fuente