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!