Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Ordnungsgemäße Verwaltung von Datenbankressourcen:Cursor und Verbindung

Das klingt nach einem großartigen Anwendungsfall für einen Python-Kontextmanager . Mit Kontextmanagern können Sie Ressourcen richtig verwalten , wie z. B. eine Datenbankverbindung, indem Sie angeben können, wie die Einrichtungs- und Abbaumethoden Ihrer Ressource funktionieren sollen . Sie können Ihren eigenen benutzerdefinierten Kontextmanager auf zwei Arten erstellen:Erstens, indem Sie Ihre Datenbankklasse umschließen und die erforderlichen Methoden für den Kontextmanager implementieren:__init__() , __enter__() , und __exit__() . Zweitens durch Verwendung eines @contextmanager decorator auf einer Funktionsdefinition und Erstellen eines Generators für Ihre Datenbankressource innerhalb dieser Funktionsdefinition. Ich werde beide Ansätze zeigen und Sie entscheiden lassen, welche Sie bevorzugen. Der __init__() Methode ist die Initialisierungsmethode für Ihren benutzerdefinierten Kontextmanager, ähnlich der Initialisierungsmethode, die für benutzerdefinierte Python-Klassen verwendet wird. Der __enter__() Methode ist Ihr Einrichtungscode für Ihren benutzerdefinierten Kontextmanager. Zuletzt der __exit()__ Methode ist Ihr Teardown Code für Ihren benutzerdefinierten Kontextmanager. Beide Ansätze verwenden diese Methoden wobei der Hauptunterschied darin besteht, dass die erste Methode diese Methoden explizit in Ihrer Klassendefinition angibt. Wobei wie beim zweiten Ansatz der gesamte Code bis zum yield Ihres Generators -Anweisung ist Ihr Initialisierungs- und Einrichtungscode und der gesamte Code nach yield -Anweisung ist Ihr Teardown-Code. Ich würde auch in Betracht ziehen, Ihre benutzerbasierten Datenbankaktionen auch in eine Benutzermodellklasse zu extrahieren. Etwas in der Art von:

benutzerdefinierter Kontextmanager:(klassenbasierter Ansatz ):

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 (überarbeitet) :'

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

Kontextmanager (Decorator-Ansatz) :

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

Dann in Ihrem User Klasse könnten Sie den Kontextmanager verwenden, indem Sie zuerst die Datei importieren und sie dann ähnlich wie zuvor verwenden:

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

Hoffentlich hilft das!