sql >> Databasteknik >  >> RDS >> Mysql

Korrekt hantering av databasresurser:markör och anslutning

Det här låter som ett bra användningsfall för en python kontexthanterare . Med kontexthanterare kan du hantera resurser på rätt sätt , till exempel en databasanslutning, genom att låta dig ange hur din resurs inställnings- och rivningsmetoder ska fungera . Du kan skapa din egen anpassade kontexthanterare på ett av två sätt:För det första genom att slå in din databasklass och implementera de metoder som krävs för kontexthanteraren:__init__() , __enter__() , och __exit__() . För det andra genom att använda en @contextmanager decorator på en funktionsdefinition och skapa en generator för din databasresurs inom nämnda funktionsdefinition. Jag kommer att visa båda tillvägagångssätten och låta dig bestämma vilken som är din preferens. __init__() metod är initieringsmetoden för din anpassade sammanhangshanterare, liknande initialiseringsmetoden som används för anpassade pythonklasser. __enter__() metod är din installationskod för din anpassade sammanhangshanterare. Till sist, __exit()__ metoden är din nedbrytning kod för din anpassade sammanhangshanterare. Båda metoderna använder dessa metoder med den största skillnaden är att den första metoden uttryckligen kommer att ange dessa metoder inom din klassdefinition. Där som i den andra metoden, all kod upp till din generators yield uttalandet är din initierings- och inställningskod och all kod efter yield uttalande är din rivningskod. Jag skulle också överväga att extrahera dina användarbaserade databasåtgärder i en användarmodellklass också. Något i stil med:

anpassad kontexthanterare:(klassbaserad metod ):

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

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

sammanhangshanterare (inredare) :

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

Sedan inom din User klass kan du använda kontexthanteraren genom att först importera filen och sedan använda den på samma sätt som tidigare:

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

Förhoppningsvis hjälper det!




  1. Best Practices för PostgreSQL-säkerhet

  2. Introduktion till användardefinierade funktioner i SQL Server

  3. Fel 1022 - Kan inte skriva; dubblettnyckel i tabellen

  4. MySQL-uppdatering ökade (inte automatiskt inkrementerade) kolumnvärden