]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- A little more verbiage to the "primaryjoin" error,
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 30 Dec 2010 17:14:32 +0000 (12:14 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 30 Dec 2010 17:14:32 +0000 (12:14 -0500)
in an unusual condition that the join condition
"works" for viewonly but doesn't work for non-viewonly,
and foreign_keys wasn't used - adds "foreign_keys" to
the suggestion.  Also add "foreign_keys" to the
suggestion for the generic "direction" error.

CHANGES
lib/sqlalchemy/orm/properties.py
test/orm/test_relationships.py

diff --git a/CHANGES b/CHANGES
index 2a6bb1e797f7e7463eeb162b3a5f893a1ffe9ebc..0878133e7df6177607c4c40dbd476991b6287fe3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -83,6 +83,13 @@ CHANGES
     improves the generation of joined-inheritance
     "load expired row" behavior.  [ticket:1992]
 
+  - A little more verbiage to the "primaryjoin" error,
+    in an unusual condition that the join condition
+    "works" for viewonly but doesn't work for non-viewonly,
+    and foreign_keys wasn't used - adds "foreign_keys" to
+    the suggestion.  Also add "foreign_keys" to the 
+    suggestion for the generic "direction" error.
+    
 - sql
   - Fixed operator precedence rules for multiple
     chains of a single non-associative operator.
index c7aa0eeea4e835ea05b1209a0fa74812e94479e2..0057f5a41b3c7a981baa09926362df7c3b864484 100644 (file)
@@ -828,16 +828,29 @@ class RelationshipProperty(StrategizedProperty):
             if not self.viewonly and criterion_as_pairs(join_condition,
                     consider_as_foreign_keys=self._user_defined_foreign_keys,
                     any_operator=True):
-                raise sa_exc.ArgumentError("Could not locate any "
-                        "equated, locally mapped column pairs for %s "
-                        "condition '%s' on relationship %s. For more "
-                        "relaxed rules on join conditions, the "
-                        "relationship may be marked as viewonly=True."
-                        % (
+                
+                err = "Could not locate any "\
+                        "foreign-key-equated, locally mapped column "\
+                        "pairs for %s "\
+                        "condition '%s' on relationship %s." % (
                             primary and 'primaryjoin' or 'secondaryjoin', 
                             join_condition, 
                             self
-                        ))
+                        )
+                
+                if not self._user_defined_foreign_keys:
+                    err += "  Ensure that the "\
+                            "referencing Column objects have a "\
+                            "ForeignKey present, or are otherwise part "\
+                            "of a ForeignKeyConstraint on their parent "\
+                            "Table, or specify the foreign_keys parameter "\
+                            "to this relationship."
+                            
+                err += "  For more "\
+                        "relaxed rules on join conditions, the "\
+                        "relationship may be marked as viewonly=True."
+
+                raise sa_exc.ArgumentError(err)
             else:
                 if self._user_defined_foreign_keys:
                     raise sa_exc.ArgumentError("Could not determine "
@@ -864,7 +877,8 @@ class RelationshipProperty(StrategizedProperty):
                             "referencing Column objects have a "
                             "ForeignKey present, or are otherwise part "
                             "of a ForeignKeyConstraint on their parent "
-                            "Table." 
+                            "Table, or specify the foreign_keys parameter " 
+                            "to this relationship."
                             % (
                                 primary and 'primaryjoin' or 'secondaryjoin', 
                                 join_condition, 
index 42340683739e52e556ed01ffffb11e442bd1924e..39480d79fd30e8560de9e53f68b34813c1e83695 100644 (file)
@@ -1949,8 +1949,43 @@ class InvalidRelationshipEscalationTest(_base.MappedTest):
 
         assert_raises_message(
             sa.exc.ArgumentError,
-            "Could not locate any equated, locally mapped column pairs "
-            "for primaryjoin condition", sa.orm.configure_mappers)
+            "Could not locate any foreign-key-equated, "
+            "locally mapped column pairs for primaryjoin "
+            "condition 'foos.id > bars.fid' on relationship "
+            "Foo.bars.  For more relaxed rules on join "
+            "conditions, the relationship may be marked as viewonly=True.",
+            sa.orm.configure_mappers)
+
+    @testing.resolve_artifact_names
+    def test_no_equated_wo_fks_works_on_relaxed(self):
+        # very unique - the join between parent/child 
+        # has no fks, but there is an fk join between two other
+        # tables in the join condition, for those users that try creating
+        # these big-long-string-of-joining-many-tables primaryjoins.
+        # in this case we don't get eq_pairs, but we hit the "works if viewonly"
+        # rule.  so here we add another clause regarding "try foreign keys".
+        mapper(Foo, foos, properties={
+            'bars':relationship(Bar,
+                            primaryjoin=and_(
+                                        bars_with_fks.c.fid==foos_with_fks.c.id,
+                                        foos_with_fks.c.id==foos.c.id,
+                                    )
+                            )})
+        mapper(Bar, bars_with_fks)
+
+        assert_raises_message(
+            sa.exc.ArgumentError,
+            "Could not locate any foreign-key-equated, locally mapped "
+             "column pairs for primaryjoin condition "
+             "'bars_with_fks.fid = foos_with_fks.id AND "
+             "foos_with_fks.id = foos.id' on relationship Foo.bars.  "
+             "Ensure that the referencing Column objects have a "
+             "ForeignKey present, or are otherwise part of a "
+             "ForeignKeyConstraint on their parent Table, or specify "
+             "the foreign_keys parameter to this relationship.  For "
+             "more relaxed rules on join conditions, the relationship "
+             "may be marked as viewonly=True.", 
+            sa.orm.configure_mappers)
 
     @testing.resolve_artifact_names
     def test_ambiguous_fks(self):
@@ -2031,8 +2066,12 @@ class InvalidRelationshipEscalationTest(_base.MappedTest):
 
         assert_raises_message(
             sa.exc.ArgumentError,
-            "Could not locate any equated, locally mapped column pairs "
-            "for primaryjoin condition", sa.orm.configure_mappers)
+            "Could not locate any foreign-key-equated, "
+            "locally mapped column pairs for primaryjoin "
+            "condition 'foos.id > foos.fid' on relationship "
+            "Foo.foos.  For more relaxed rules on join "
+            "conditions, the relationship may be marked as viewonly=True.",
+            sa.orm.configure_mappers)
 
     @testing.resolve_artifact_names
     def test_no_equated_viewonly(self):
@@ -2301,8 +2340,15 @@ class InvalidRelationshipEscalationTestM2M(_base.MappedTest):
         mapper(Bar, bars)
         assert_raises_message(
             sa.exc.ArgumentError,
-            "Could not locate any equated, locally mapped column pairs for "
-            "primaryjoin condition ",
+            r"Could not locate any foreign-key-equated, locally mapped "
+             "column pairs for primaryjoin condition 'foos.id > "
+             "foobars_with_fks.fid' on relationship Foo.bars.  Ensure "
+             "that the referencing Column objects have a ForeignKey "
+             "present, or are otherwise part of a ForeignKeyConstraint "
+             "on their parent Table, or specify the foreign_keys "
+             "parameter to this relationship.  For more relaxed "
+             "rules on join conditions, the relationship may be marked "
+             "as viewonly=True.", 
             configure_mappers)
 
         sa.orm.clear_mappers()
@@ -2352,7 +2398,7 @@ class InvalidRelationshipEscalationTestM2M(_base.MappedTest):
 
         assert_raises_message(
             sa.exc.ArgumentError,
-            "Could not locate any equated, locally mapped column pairs for "
+            "Could not locate any foreign-key-equated, locally mapped column pairs for "
             "secondaryjoin condition", sa.orm.configure_mappers)
 
 class ActiveHistoryFlagTest(_fixtures.FixtureTest):