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!