From c6538b6b3400cbfa939d4e3e8d0f0530e0530e9d Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 8 Dec 2006 03:27:09 +0000 Subject: [PATCH] - MySQL detects errors 2006 (server has gone away) and 2014 (commands out of sync) and invalidates the connection on which it occured. --- CHANGES | 2 ++ lib/sqlalchemy/databases/mysql.py | 16 ++++++++++++++++ lib/sqlalchemy/pool.py | 11 +++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 45caad5772..9d3e5e8ed2 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,8 @@ time-intensive to generate log messages - fixed bug in cascade rules whereby the entire object graph could be unnecessarily cascaded on the save/update cascade +- MySQL detects errors 2006 (server has gone away) and 2014 +(commands out of sync) and invalidates the connection on which it occured. - added keywords for EXCEPT, INTERSECT, EXCEPT ALL, INTERSECT ALL [ticket:247] - added label() function to Select class, when scalar=True is used diff --git a/lib/sqlalchemy/databases/mysql.py b/lib/sqlalchemy/databases/mysql.py index 3253474643..662d276e93 100644 --- a/lib/sqlalchemy/databases/mysql.py +++ b/lib/sqlalchemy/databases/mysql.py @@ -289,6 +289,22 @@ class MySQLDialect(ansisql.ANSIDialect): def preparer(self): return MySQLIdentifierPreparer(self) + def do_executemany(self, cursor, statement, parameters, **kwargs): + try: + cursor.executemany(statement, parameters) + except mysql.OperationalError, o: + if o.args[0] == 2006 or o.args[0] == 2014: + cursor.invalidate() + raise o + def do_execute(self, cursor, statement, parameters, **kwargs): + try: + cursor.execute(statement, parameters) + except mysql.OperationalError, o: + if o.args[0] == 2006 or o.args[0] == 2014: + cursor.invalidate() + raise o + + def do_rollback(self, connection): # some versions of MySQL just dont support rollback() at all.... try: diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index 99504e1368..8e74f0343a 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -187,7 +187,7 @@ class _ConnectionFairy(object): """proxies a DBAPI connection object and provides return-on-dereference support""" def __init__(self, pool): self._threadfairy = _ThreadFairy(self) - self.cursors = weakref.WeakKeyDictionary() + self.cursors = {} self.__pool = pool self.__counter = 0 try: @@ -220,8 +220,9 @@ class _ConnectionFairy(object): self.__counter +=1 return self def close_open_cursors(self): - for c in list(self.cursors): - c.close() + if self.cursors is not None: + for c in list(self.cursors): + c.close() def close(self): self.__counter -=1 if self.__counter == 0: @@ -255,13 +256,15 @@ class _CursorFairy(object): self.__parent = parent self.__parent.cursors[self]=True self.cursor = cursor + def invalidate(self): + self.__parent.invalidate() def close(self): if self in self.__parent.cursors: del self.__parent.cursors[self] self.cursor.close() def __getattr__(self, key): return getattr(self.cursor, key) - + class SingletonThreadPool(Pool): """Maintains one connection per each thread, never moving a connection to a thread other than the one which it was created in. -- 2.47.2