]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
for string deferred evals, don't return the underlying Column, rely upon the original...
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 29 Jan 2010 18:55:03 +0000 (18:55 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 29 Jan 2010 18:55:03 +0000 (18:55 +0000)
reduces duplication of the "columns[0]" rule and removes potentially surprise behavior from the eval

lib/sqlalchemy/ext/declarative.py
test/ext/test_declarative.py

index 816bcf3e8745a2b4d699858d74fbacec4b582575..234aac17caed8325a628b12b04f5c9b9abf51085 100644 (file)
@@ -585,14 +585,16 @@ class _GetColumns(object):
     def __init__(self, cls):
         self.cls = cls
     def __getattr__(self, key):
+        
         mapper = class_mapper(self.cls, compile=False)
-        if not mapper:
-            return getattr(self.cls, key)
-        else:
+        if mapper:
             prop = mapper.get_property(key)
             if not isinstance(prop, ColumnProperty):
-                raise exceptions.InvalidRequestError("Property %r is not an instance of ColumnProperty (i.e. does not correspnd directly to a Column)." % key)
-            return prop.columns[0]
+                raise exceptions.InvalidRequestError(
+                                        "Property %r is not an instance of"
+                                        " ColumnProperty (i.e. does not correspond"
+                                        " directly to a Column)." % key)
+        return getattr(self.cls, key)
 
 
 def _deferred_relation(cls, prop):
index cf5f72050f66434666428410deb87214c9c54e3d..52cea62c4f232dfff646249b4e3fe4460a976a33 100644 (file)
@@ -156,6 +156,25 @@ class DeclarativeTest(DeclarativeTestBase):
             rel = relation("User", primaryjoin="User.addresses==Foo.id")
         assert_raises_message(exc.InvalidRequestError, "'addresses' is not an instance of ColumnProperty", compile_mappers)
 
+    def test_string_dependency_resolution_no_magic(self):
+        """test that full tinkery expressions work as written"""
+        
+        class User(Base, ComparableEntity):
+            __tablename__ = 'users'
+            id = Column(Integer, primary_key=True)
+            addresses = relation("Address", 
+                primaryjoin="User.id==Address.user_id.prop.columns[0]")
+        
+        class Address(Base, ComparableEntity):
+            __tablename__ = 'addresses'
+            id = Column(Integer, primary_key=True)
+            user_id = Column(Integer, ForeignKey('users.id'))
+        
+        compile_mappers()
+        eq_(
+            str(User.addresses.prop.primaryjoin), "users.id = addresses.user_id"
+        )
+        
     def test_string_dependency_resolution_in_backref(self):
         class User(Base, ComparableEntity):
             __tablename__ = 'users'