Reintentar una connexió a la base de dades amb Python
Fins ahir tenia un problema prou complicat: estic treballant en un programa en Python que requereix múltiples i constants connexions a una base de dades mySQL. Quan treballava en local, no tenia cap problema però, quan executava el programa en màquines diferents apuntant cap a un servidor de bases de dades (com passaria, per exemple, en un cluster), de tant en tant i de manera aleatòria, el servidor mySQL es quedava “tonto” i no responia. Aquesta pèrdua de connexió feia que el programa “petés”.
Amb l’administrador de sistemes del grup hem treballat per mirar què passa amb el mySQL ja que sembla que el problema és allà, però no hem trobat solució. No hi ha ni problemes ni amb el límit màxim de connexions, ni amb la memòria, cpu,… en fi, per algun motiu que desconeixem, el servidor es satura i té petites penjades. Així dons, la solució passa per fer alguna cosa al programa perquè no peti quan la base de dades no respongui.
La solució està en les “excepcions” (de l’anglès exception, desconec si aquesta traducció literal és vàlida). És a dir, per defecte, quan python intenta accedir a la base de dades, si aquesta no respon, es crea una excepció que, si no se li diu res, provoca la sortida del programa. La idea està en modificar aquesta excepció perquè quan python vegi que la base de dades no respon, la solució no sigui sortir del programa sinó reintentar-ho. He jugat amb el try i except.
db = DB()
cursor = db.cursor()
sql = ’select count(*) from molecules’
number = cursor.execute(sql)class DB:
def cursor(self):
try:
bd = MySQLdb.connect(host=HOSTNAME, user=”USERNAMEl”, passwd=”PASSWD”,db=”DB_NAME)
cursor = bd.cursor()
return cursor
except MySQLdb.OperationalError, message:
return self.cursor()
La primera part del codi inicia la classe DB i n’obté el “cursor”, operador amb el que realitzarem les crides sql. La part més interessant però és la classe DB, que conté la funció “cursor”. Aquesta funció connecta amb la base de dades i retorna el “cursor”, comanda dins l’ordre try. Però, el fet de jugar amb el try i except fa que el programa primer provi el que hi ha a try però, si falla i troba una excepció que coincideix amb la indicada a except, en l’exemple MySQLdb.OperationalError, en comptes d’aturar l’execució del programa (el que faria per defecte) fa el que se li diu, en aquest cas que torni a executar la funció.



