]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Error message when a string arg sent to :func:`.relationship` which
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 12 Dec 2013 17:49:57 +0000 (12:49 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 12 Dec 2013 17:49:57 +0000 (12:49 -0500)
doesn't resolve to a class or mapper has been corrected to work
the same way as when a non-string arg is received, which indicates
the name of the relationship which had the configurational error.
[ticket:2888]

doc/build/changelog/changelog_08.rst
lib/sqlalchemy/orm/relationships.py
test/ext/declarative/test_basic.py

index 0902ff7e464ef8d8063a0935610e31bf9c9e1b35..2cd9b58554fae78938395f36d49c528f711d0022 100644 (file)
@@ -8,6 +8,19 @@
     .. include:: changelog_07.rst
         :start-line: 5
 
+.. changelog::
+    :version: 0.8.5
+
+    .. change::
+        :tags: bug, declarative
+        :versions: 0.9.0b2
+        :tickets: 2888
+
+        Error message when a string arg sent to :func:`.relationship` which
+        doesn't resolve to a class or mapper has been corrected to work
+        the same way as when a non-string arg is received, which indicates
+        the name of the relationship which had the configurational error.
+
 .. changelog::
     :version: 0.8.4
 
index 8296be60a23ea062524432b322c9ef8ef7c28c10..c1cf07fbe1d9915d7c160c08c0e4a4381787cad0 100644 (file)
@@ -1348,23 +1348,21 @@ class RelationshipProperty(StrategizedProperty):
         This is a lazy-initializing static attribute.
 
         """
-        if isinstance(self.argument, type):
-            mapper_ = mapperlib.class_mapper(self.argument,
-                    configure=False)
-        elif isinstance(self.argument, mapperlib.Mapper):
-            mapper_ = self.argument
-        elif util.callable(self.argument):
-
-            # accept a callable to suit various deferred-
-            # configurational schemes
+        if util.callable(self.argument) and \
+            not isinstance(self.argument, (type, mapperlib.Mapper)):
+            argument = self.argument()
+        else:
+            argument = self.argument
 
-            mapper_ = mapperlib.class_mapper(self.argument(),
+        if isinstance(argument, type):
+            mapper_ = mapperlib.class_mapper(argument,
                     configure=False)
+        elif isinstance(self.argument, mapperlib.Mapper):
+            mapper_ = argument
         else:
             raise sa_exc.ArgumentError("relationship '%s' expects "
                     "a class or a mapper argument (received: %s)"
-                    % (self.key, type(self.argument)))
-        assert isinstance(mapper_, mapperlib.Mapper), mapper_
+                    % (self.key, type(argument)))
         return mapper_
 
     @util.memoized_property
index f5e7f2aa777a5c22d583e8abe36a6ac2c10f88fb..b119e356f7946e122e2e1c8f9d0132c458ae0f08 100644 (file)
@@ -143,6 +143,38 @@ class DeclarativeTest(DeclarativeTestBase):
         assert class_mapper(Bar).get_property('some_data').columns[0] \
             is t.c.data
 
+    def test_relationship_level_msg_for_invalid_callable(self):
+        class A(Base):
+            __tablename__ = 'a'
+            id = Column(Integer, primary_key=True)
+        class B(Base):
+            __tablename__ = 'b'
+            id = Column(Integer, primary_key=True)
+            a_id = Column(Integer, ForeignKey('a.id'))
+            a = relationship('a')
+        assert_raises_message(
+            sa.exc.ArgumentError,
+            "relationship 'a' expects a class or a mapper "
+            "argument .received: .*Table",
+            configure_mappers
+        )
+
+    def test_relationship_level_msg_for_invalid_object(self):
+        class A(Base):
+            __tablename__ = 'a'
+            id = Column(Integer, primary_key=True)
+        class B(Base):
+            __tablename__ = 'b'
+            id = Column(Integer, primary_key=True)
+            a_id = Column(Integer, ForeignKey('a.id'))
+            a = relationship(A.__table__)
+        assert_raises_message(
+            sa.exc.ArgumentError,
+            "relationship 'a' expects a class or a mapper "
+            "argument .received: .*Table",
+            configure_mappers
+        )
+
     def test_difficult_class(self):
         """test no getattr() errors with a customized class"""