python - para - ¿Cómo habilitar la reconexión automática del cliente MySQL con MySQLdb?
python mysql select (6)
Otra apuesta es que trabajas en torno a las conexiones caídas con código.
Una forma de hacerlo sería la siguiente:
import MySQLdb
class DB:
conn = None
def connect(self):
self.conn = MySQLdb.connect()
def cursor(self):
try:
return self.conn.cursor()
except (AttributeError, MySQLdb.OperationalError):
self.connect()
return self.conn.cursor()
db = DB()
cur = db.cursor()
# wait a long time for the Mysql connection to timeout
cur = db.cursor()
# still works
Me encontré con la forma PHP de hacer el truco:
my_bool reconnect = 1;
mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect);
pero no tuve suerte con MySQLdb (python-mysql).
¿Alguien puede dar una pista? Gracias.
Si está utilizando Ubuntu Linux, se agregó un parche al paquete python-mysql que agregó la capacidad de establecer esa misma opción MYSQL_OPT_RECONNECT (consulte aquí ). No lo he intentado sin embargo.
Lamentablemente, el parche se eliminó más tarde debido a un conflicto con la conexión automática y las transacciones (que se describen aquí ).
Los comentarios de esa página dicen: 1.2.2-7 Publicado en intrépido-lanzamiento en 2008-06-19
python-mysqldb (1.2.2-7) inestable; urgencia = baja
[Sandro Tosi] * debian / control - lista de líneas de elementos en la descripción comienza con 2 espacios, para evitar el formateo en las páginas web (Cierra: # 480341)
[Bernd Zeimetz] * debian / patches / 02_reconnect.dpatch: - Parche que cae: Comenta en Storm que explica el problema:
# Here is another sad story about bad transactional behavior. MySQL
# offers a feature to automatically reconnect dropped connections.
# What sounds like a dream, is actually a nightmare for anyone who
# is dealing with transactions. When a reconnection happens, the
# currently running transaction is transparently rolled back, and
# everything that was being done is lost, without notice. Not only
# that, but the connection may be put back in AUTOCOMMIT mode, even
# when that''s not the default MySQLdb behavior. The MySQL developers
# quickly understood that this is a terrible idea, and removed the
# behavior in MySQL 5.0.3. Unfortunately, Debian and Ubuntu still
# have a patch right now which *reenables* that behavior by default
# even past version 5.0.3.
Tuve problemas con la solución propuesta porque no captó la excepción. No estoy seguro por qué.
He resuelto el problema con la declaración ping(True)
que creo que es más clara:
import MySQLdb
con=MySQLdb.Connect()
con.ping(True)
cur=con.cursor()
Entendido desde aquí: http://www.neotitans.com/resources/python/mysql-python-connection-error-2006.html
Tuve un problema similar con MySQL y Python, y la solución que funcionó para mí fue actualizar MySQL a 5.0.27 (en Fedora Core 6, su sistema puede funcionar bien con una versión diferente).
Intenté muchas otras cosas, incluso parchear las bibliotecas de Python, pero actualizar la base de datos fue mucho más fácil y (creo) una mejor decisión.
puedes separar el compromiso y el cierre de la conexión ... eso no es lindo, pero lo hace.
class SqlManager(object):
"""
Class that handle the database operation
"""
def __init__(self,server, database, username, pswd):
self.server = server
self.dataBase = database
self.userID = username
self.password = pswd
def Close_Transation(self):
"""
Commit the SQL Query
"""
try:
self.conn.commit()
except Sql.Error, e:
print "-- reading SQL Error %d: %s" % (e.args[0], e.args[1])
def Close_db(self):
try:
self.conn.close()
except Sql.Error, e:
print "-- reading SQL Error %d: %s" % (e.args[0], e.args[1])
def __del__(self):
print "close connection with database.."
self.conn.close()
cursor.execute()
este problema creando una función que ajusta el método cursor.execute()
ya que eso es lo que arrojaba la excepción MySQLdb.OperationalError
. El otro ejemplo anterior implica que es el método conn.cursor()
que arroja esta excepción.
import MySQLdb
class DB:
conn = None
def connect(self):
self.conn = MySQLdb.connect()
def query(self, sql):
try:
cursor = self.conn.cursor()
cursor.execute(sql)
except (AttributeError, MySQLdb.OperationalError):
self.connect()
cursor = self.conn.cursor()
cursor.execute(sql)
return cursor
db = DB()
sql = "SELECT * FROM foo"
cur = db.query(sql)
# wait a long time for the Mysql connection to timeout
cur = db.query(sql)
# still works