Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Gerenciamento adequado dos recursos do banco de dados:cursor e conexão


Parece um ótimo caso de uso para um gerenciador de contexto do Python . Os gerenciadores de contexto permitem que você gerencie recursos adequadamente , como uma conexão de banco de dados, permitindo que você especifique como os métodos de configuração e desmontagem do seu recurso devem funcionar . Você pode criar seu próprio gerenciador de contexto personalizado de duas maneiras:Primeiro, envolvendo sua classe de banco de dados e implementando os métodos necessários para o gerenciador de contexto:__init__() , __enter__() e __exit__() . Segundo, utilizando um @contextmanager decorador em uma definição de função e criando um gerador para seu recurso de banco de dados dentro dessa definição de função. Vou mostrar as duas abordagens e deixar você decidir qual é a sua preferência. O __init__() é o método de inicialização para seu gerenciador de contexto personalizado, semelhante ao método de inicialização usado para classes python personalizadas. O __enter__() método é seu código de configuração para seu gerenciador de contexto personalizado. Por último, o __exit()__ método é sua desmontagem código para seu gerenciador de contexto personalizado. Ambas as abordagens utilizam esses métodos com a principal diferença sendo o primeiro método declarará explicitamente esses métodos dentro de sua definição de classe. Onde, como na segunda abordagem, todo o código até o yield do seu gerador declaração é seu código de inicialização e configuração e todo o código após o yield declaração é o seu código de desmontagem. Eu também consideraria extrair suas ações de banco de dados baseadas em usuário em uma classe de modelo de usuário também. Algo na linha de:

gerenciador de contexto personalizado:(abordagem baseada em classe ):
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 (refatorado) :'
# 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))

gerenciador de contexto (abordagem do 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()

Em seguida, dentro do seu User class você pode usar o gerenciador de contexto importando primeiro o arquivo e depois usando-o semelhante a antes:
with my_database() as db:
   sql = <whatever sql stmt you wish to execute>
   #db action 
   db.execute(sql)

Espero que isso ajude!