Commits

Mike Bayer committed f0c2b5e

- MySQL detects errors 2006 (server has gone away) and 2014
(commands out of sync) and invalidates the connection on which it occured.

Comments (0)

Files changed (3)

   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

lib/sqlalchemy/databases/mysql.py

     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:

lib/sqlalchemy/pool.py

     """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:
         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:
         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.