Mysql
 sql >> Base de données >  >> RDS >> Mysql

Bonne gestion des ressources de la base de données :curseur et connexion

Cela ressemble à un excellent cas d'utilisation pour un python gestionnaire de contexte . Les gestionnaires de contexte vous permettent de gérer correctement les ressources , comme une connexion à une base de données, en vous permettant de spécifier comment les méthodes d'installation et de démontage de votre ressource doivent fonctionner . Vous pouvez créer votre propre gestionnaire de contexte personnalisé de deux manières :premièrement, en encapsulant votre classe de base de données et en implémentant les méthodes requises pour le gestionnaire de contexte :__init__() , __enter__() , et __exit__() . Deuxièmement, en utilisant un @contextmanager décorateur sur une définition de fonction et création d'un générateur pour votre ressource de base de données dans ladite définition de fonction. Je vais montrer les deux approches et vous laisser décider laquelle est votre préférence. Le __init__() method est la méthode d'initialisation pour votre gestionnaire de contexte personnalisé, similaire à la méthode d'initialisation utilisée pour les classes python personnalisées. Le __enter__() method est votre code de configuration pour votre gestionnaire de contexte personnalisé. Enfin, le __exit()__ la méthode est votre démontage code pour votre gestionnaire de contexte personnalisé. Les deux approches utilisent ces méthodes la principale différence étant que la première méthode énoncera explicitement ces méthodes dans votre définition de classe. Où, comme dans la deuxième approche, tout le code jusqu'au yield de votre générateur déclaration est votre code d'initialisation et de configuration et tout le code après le yield déclaration est votre code de démontage. J'envisagerais également d'extraire vos actions de base de données basées sur l'utilisateur dans une classe de modèle utilisateur. Quelque chose comme :

gestionnaire de contexte personnalisé :(approche basée sur les classes ):

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 (refactorisé) :'

# 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))

gestionnaire de contexte (approche décorateur) :

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()

Puis dans votre User classe, vous pouvez utiliser le gestionnaire de contexte en important d'abord le fichier, puis en l'utilisant comme avant :

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

J'espère que cela aide !