Commits

Mike Bayer committed 72cf748

- [bug] Fixed issue whereby attribute-based
column access on a row would raise
AttributeError with non-C version,
NoSuchColumnError with C version. Now
raises AttributeError in both cases.
[ticket:2398]

Comments (0)

Files changed (4)

     in particular when orm query.count()
     were called.  [ticket:2427]
 
+  - [bug] Fixed issue whereby attribute-based
+    column access on a row would raise 
+    AttributeError with non-C version,
+    NoSuchColumnError with C version.  Now
+    raises AttributeError in both cases.
+    [ticket:2398]
+
   - [feature] Added support for SQL standard
     common table expressions (CTE), allowing
     SELECT objects as the CTE source (DML

lib/sqlalchemy/cextension/resultproxy.c

     else
         return tmp;
 
-    return BaseRowProxy_subscript(self, name);
+    tmp = BaseRowProxy_subscript(self, name);
+    if (tmp == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) {
+        PyErr_Format(
+                PyExc_AttributeError, 
+                "Could not locate column in row for column '%.200s'",
+                PyString_AsString(name)
+            );
+        return NULL;
+    }
+    return tmp;
 }
 
 /***********************

lib/sqlalchemy/engine/base.py

 
         def __getattr__(self, name):
             try:
-                # TODO: no test coverage here
                 return self[name]
             except KeyError, e:
                 raise AttributeError(e.args[0])

test/sql/test_query.py

         eq_(r[users.c.user_name], 'jack')
         eq_(r.user_name, 'jack')
 
+    def test_column_accessor_err(self):
+        r = testing.db.execute(select([1])).first()
+        assert_raises_message(
+            AttributeError,
+            "Could not locate column in row for column 'foo'",
+            getattr, r, "foo"
+        )
+        assert_raises_message(
+            KeyError,
+            "Could not locate column in row for column 'foo'",
+            lambda: r['foo']
+        )
+
     @testing.requires.dbapi_lastrowid
     def test_native_lastrowid(self):
         r = testing.db.execute(