AttributeError in Connection._handle_dbapi_exception [test+patch]

Issue #2691 resolved
Former user created an issue

(original reporter: elic) I found a small bug in sqlalchemy.engine.base:Connection._handle_dbapi_exception: Under certain conditions (the connection already being closed is part of it), the line calculating is_disconnect = ... throws an AttributeError while attempting to access self.__connection. The bug seems to be present in 0.7.0 through 0.8.0. Test script is attached.

The following patch seems to fix things:

diff --git a/sqlalchemy/engine/base.py b/sqlalchemy/engine/base.py
index 6242f08..a8bdf7b 100644
--- a/sqlalchemy/engine/base.py
+++ b/sqlalchemy/engine/base.py
@@ -1007,6 +1007,7 @@ class Connection(Connectable):
                 context.handle_dbapi_exception(e)

             is_disconnect = isinstance(e, self.dialect.dbapi.Error) and \
+                hasattr(self, "_Connection__connection") and \
                 self.dialect.is_disconnect(e, self.__connection, cursor)

             if is_disconnect:

Comments (4)

  1. Mike Bayer repo owner

    the NullPool appears to be needed since the DBAPI cursor is still valid if the connection is just returned to the pool. But closing the cursor explicitly as well as the connection eliminates the need for nullpool:

    from sqlalchemy.engine import create_engine
    
    engine = create_engine("postgresql://scott:tiger@localhost/test")
    
    conn = engine.connect()
    result = conn.execute("select 1")
    result.cursor.close()
    conn.close()
    list(result)
    

    we have a "closed" attribute that we can use here more expediently:

    diff -r 6bdd3bb93fd18a4aec54ee2a836875a922dcaab3 lib/sqlalchemy/engine/base.py
    --- a/lib/sqlalchemy/engine/base.py Mon Apr 01 15:41:57 2013 -0400
    +++ b/lib/sqlalchemy/engine/base.py Tue Apr 02 16:56:18 2013 -0400
    @@ -1007,6 +1007,7 @@
                     context.handle_dbapi_exception(e)
    
                 is_disconnect = isinstance(e, self.dialect.dbapi.Error) and \
    +                not self.closed and \
                     self.dialect.is_disconnect(e, self.__connection, cursor)
    
                 if is_disconnect:
    

    needs a unit test somewhere in test/engine/test_reconnect.py.

    high priority because it's actually a core bug, as opposed to some missing feature or something.

  2. Log in to comment