Ja he parlat alguna altra vegada de SQLAlchemy.
Com sabreu els que us hi heu dedicat alguna vegada, la gestió de les connexions a les bases de dades és un punt crític a les aplicacions amb diversos usuaris simultanis. Bé, és extensible a qualssevol recursos escassos.
Una solució que proposen (i deixen ben clar que no és l’única) és la següent:
from contextlib import contextmanager
sessions = sessionmaker (...)
@contextmanager
def entorn_sessio ():
sessio = sessions()
try:
yield sessio
sessio.commit()
except:
sessio.rollback()
raise
finally:
sessio.close()
def fer_feina():
# En acabar-se el WITH el bloc torna a entorn_sessio, just després del YIELD.
# Farà el commit
# Si hi ha un error rebrem l'excepció
# En tot cas allibera la connexió a la base de dades
try:
with entorn_sessio() as una_sessio:
# El que hi ha dins del WITH pot fer l'accés a base de dades
llibre_nou = Llibre(autor="Pierre Lemaître", titol="Couleurs de l'incendie")
una_sessio.add (llibre_nou)
except:
# Tractar els errors des del punt de vista funcional, sense amoïnar-se per la connexió a la base de dades
# I aquí seguim fent coses que no necessiten base de dades
fer_mes_feina_sense_base_dades ()
L’he trobat molt elegant i a més m’agrada perquè:
- Queda clar en quin bloc es fa accés a base de dades (el que és dins del with). Això convida a fer-lo curt i, si no ho és, a repensar-ho una mica.
- Fa una gestió global del recurs (l’accés a base de dades) de forma bastant còmoda, que em sembla fàcil d’estandarditzar en tota una aplicació o en un equip de treball.
- En cap cas es queden connexions obertes (si se segueix el patró a tot arreu, és clar).
- M’ha permès aprofundir en el yield (no l’havia fet servir mai, encara… i és que m’agrada el Python, però vaig aprendre a programar amb BASIC i Pascal, que són molt tradicionals).
L’he començat a fer servir per una aplicació d’ús personal, amb una variant: un “entorn_sessio” per a actualitzacions (com el que hi ha a l’exemple de dalt) i un altre només per consultes, que incondicionalment fa un rollback() al final.
Si bé aquest mètode em sembla bo, no hi ha solució universal a aquests problemes. I gairebé és tan important assegurar-se que dins d’una aplicació es fa a tot arreu de la mateixa manera com la correcció de la solució per ella mateixa.
22/3/2019: Exemple retocat.