sql >> Base de Datos >  >> RDS >> Mysql

Correcta gestión de los recursos de la base de datos:cursor y conexión

Esto suena como un gran caso de uso para un administrador de contexto de python . Los administradores de contexto le permiten administrar adecuadamente los recursos , como una conexión a una base de datos, al permitirle especificar cómo deben funcionar los métodos de configuración y desconexión de su recurso . Puede crear su propio administrador de contexto personalizado de una de dos maneras:primero, ajustando su clase de base de datos e implementando los métodos necesarios para el administrador de contexto:__init__() , __enter__() y __exit__() . En segundo lugar, utilizando un @contextmanager decorador en una definición de función y creando un generador para su recurso de base de datos dentro de dicha definición de función. Mostraré ambos enfoques y le dejaré decidir cuál es su preferencia. El __init__() method es el método de inicialización para su administrador de contexto personalizado, similar al método de inicialización utilizado para las clases de python personalizadas. El __enter__() método es su código de configuración para su administrador de contexto personalizado. Por último, el __exit()__ el método es tu desmontaje código para su administrador de contexto personalizado. Ambos enfoques utilizan estos métodos con la principal diferencia de que el primer método indicará explícitamente estos métodos dentro de la definición de su clase. Mientras que en el segundo enfoque, todo el código hasta el yield de su generador declaración es su código de inicialización y configuración y todo el código después del yield declaración es su código de desmontaje. También consideraría extraer las acciones de la base de datos basadas en el usuario en una clase de modelo de usuario. Algo como:

administrador de contexto personalizado:(enfoque basado en clases ):

import pymysql

class MyDatabase():
    def __init__(self):
        self.host = '127.0.0.1'
        self.user = 'root'
        self.password = ''
        self.db = 'API'

        self.con = None
        self.cur = None

    def __enter__(self):
        # connect to database
        self.con = pymysql.connect(host=self.host, user=self.user, password=self.password, db=self.db, cursorclass=pymysql.cursors.DictCursor, autocommit=True)
        self.cur = self.con.cursor()
        return self.cur

    def __exit__(self, exc_type, exc_val, traceback):
        # params after self are for dealing with exceptions
        self.con.close()

user.py (refactorizado) :'

# import your custom context manager created from the step above
# if you called your custom context manager file my_database.py: from my_database import MyDatabase

import <custom_context_manager>

class User:
    def getUser(self, id):
        sql = 'SELECT * from users where id = %d'
        with MyDatabase() as db: 
            db.execute(sql, (id))
            result = db.fetchall()

        return result

    def getAllUsers(self):
        sql = 'SELECT * from users'
        with MyDatabase() as db: 
            db.execute(sql)
            result = db.fetchall()
        return result

    def AddUser(self, firstName, lastName, email):
        sql = "INSERT INTO `users` (`firstName`, `lastName`, `email`) VALUES (%s, %s, %s)"
        with MyDatabase() as db:
            db.execute(sql, (firstName, lastName, email))

administrador de contexto (enfoque de decorador) :

from contextlib import contextmanager
import pymysql


@contextmanager
def my_database():
    try:
        host = '127.0.0.1'
        user = 'root'
        password = ''
        db = 'API'
        con = pymysql.connect(host=host, user=user, password=password, db=db, cursorclass=pymysql.cursors.DictCursor, autocommit=True)
        cur = con.cursor()
        yield cur
    finally:
        con.close()

Luego dentro de su User clase, puede usar el administrador de contexto importando primero el archivo y luego usándolo de manera similar a como se hizo antes:

with my_database() as db:
   sql = <whatever sql stmt you wish to execute>
   #db action 
   db.execute(sql)

¡Espero que eso ayude!