sql >> Database >  >> RDS >> Mysql

Correct beheer van databasebronnen:cursor en verbinding

Dit klinkt als een geweldige use case voor een python contextmanager . Met contextmanagers kunt u bronnen goed beheren , zoals een databaseverbinding, door u toe te staan ​​te specificeren hoe de methoden voor het opzetten en afbreken van uw bron moeten werken . U kunt op twee manieren uw eigen aangepaste contextmanager maken:Ten eerste door uw databaseklasse in te pakken en de vereiste methoden voor de contextmanager te implementeren:__init__() , __enter__() , en __exit__() . Ten tweede, door gebruik te maken van een @contextmanager decorateur op een functiedefinitie en het creëren van een generator voor uw databaseresource binnen de functiedefinitie. Ik zal beide benaderingen laten zien en u laten beslissen welke uw voorkeur heeft. De __init__() methode is de initialisatiemethode voor uw aangepaste contextmanager, vergelijkbaar met de initialisatiemethode die wordt gebruikt voor aangepaste python-klassen. De __enter__() methode is uw installatiecode voor uw aangepaste contextmanager. Ten slotte, de __exit()__ methode is jouw demontage code voor uw aangepaste contextmanager. Beide benaderingen gebruiken deze methoden met als belangrijkste verschil dat de eerste methode deze methoden expliciet vermeldt in uw klassendefinitie. Waar, zoals in de tweede benadering, alle code tot aan de yield . van uw generator statement is uw initialisatie- en configuratiecode en alle code na de yield statement is je demontagecode. Ik zou ook overwegen om uw op gebruikers gebaseerde databaseacties ook in een gebruikersmodelklasse te extraheren. Iets in de trant van:

aangepaste contextmanager:(op klassen gebaseerde benadering ):

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

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

contextmanager (decorateurbenadering) :

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

Vervolgens binnen uw User class kunt u de contextmanager gebruiken door eerst het bestand te importeren en het vervolgens op dezelfde manier te gebruiken als voorheen:

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

Hopelijk helpt dat!




  1. Hoe de tafel in orakel te laten vallen

  2. Hoe u kunt profiteren van de nieuwe partitioneringsfuncties in PostgreSQL 11

  3. Meerdere PostgreSQL-instanties op één host uitvoeren

  4. Meerdere buitenlandse sleutels?