]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- an explicit check occurs when a synonym() is used with
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 4 Dec 2009 01:51:23 +0000 (01:51 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 4 Dec 2009 01:51:23 +0000 (01:51 +0000)
    map_column=True, when a ColumnProperty (deferred or otherwise)
    exists separately in the properties dictionary sent to mapper
    with the same keyname.   Instead of silently replacing
    the existing property (and possible options on that property),
    an error is raised.  [ticket:1633]

CHANGES
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/strategies.py
test/orm/test_mapper.py

diff --git a/CHANGES b/CHANGES
index a8d4a0109e74d2a0354c0a537656142ff6945bda..052848fbf94b582b13abc7fa560f01939090105a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -69,6 +69,13 @@ CHANGES
     in filter criterion against the dynamic relation.
     [ticket:1531]
 
+  - an explicit check occurs when a synonym() is used with 
+    map_column=True, when a ColumnProperty (deferred or otherwise)
+    exists separately in the properties dictionary sent to mapper
+    with the same keyname.   Instead of silently replacing 
+    the existing property (and possible options on that property), 
+    an error is raised.  [ticket:1633]
+    
   - a "dynamic" loader sets up its query criterion at construction
     time so that the actual query is returned from non-cloning
     accessors like "statement".
index 1c7c37ead7861ca866f213c20f885a8eb071f9da..9b5583afafd928dc1777d2ef2649fd6061ed1260 100644 (file)
@@ -616,8 +616,26 @@ class Mapper(object):
                     raise sa_exc.ArgumentError(
                         "Can't compile synonym '%s': no column on table '%s' named '%s'" 
                          % (prop.name, self.mapped_table.description, key))
-                self._configure_property(prop.name, ColumnProperty(self.mapped_table.c[key]), init=init, setparent=setparent)
-
+                elif self.mapped_table.c[key] in self._columntoproperty and \
+                        self._columntoproperty[self.mapped_table.c[key]].key == prop.name:
+                    raise sa_exc.ArgumentError(
+                                "Can't call map_column=True for synonym %r=%r, "
+                                "a ColumnProperty already exists keyed to the name %r "
+                                "for column %r" % 
+                                (key, prop.name, prop.name, key)
+                            )
+                p = ColumnProperty(self.mapped_table.c[key])
+                self._configure_property(prop.name, p, init=init, setparent=setparent)
+                p._mapped_by_synonym = key
+        
+        if key in self._props and getattr(self._props[key], '_mapped_by_synonym', False):
+            syn = self._props[key]._mapped_by_synonym
+            raise sa_exc.ArgumentError(
+                        "Can't call map_column=True for synonym %r=%r, "
+                        "a ColumnProperty already exists keyed to the name "
+                        "%r for column %r" % (syn, key, key, syn)
+                    )
+            
         self._props[key] = prop
         prop.key = key
 
index ff80fd6e6b87999f985dfa38e8cfb25cf86faa0c..7c56e1182af50084e422a1a9bfb80a92fff17d31 100644 (file)
@@ -195,7 +195,7 @@ log.class_logger(CompositeColumnLoader)
     
 class DeferredColumnLoader(LoaderStrategy):
     """Strategize the loading of a deferred column-based MapperProperty."""
-    
+
     def create_row_processor(self, selectcontext, path, mapper, row, adapter):
         col = self.columns[0]
         if adapter:
index 62bf636b898aec86c71d1065d1b3ab41604818ed..4c174ba24dcb9d6b0bfeb90af188493d951dff23 100644 (file)
@@ -805,6 +805,26 @@ class MapperTest(_fixtures.FixtureTest):
         eq_(u.name, 'foo')
         eq_(assert_col, [('get', 'jack'), ('set', 'foo'), ('get', 'foo')])
 
+    @testing.resolve_artifact_names
+    def test_synonym_map_column_conflict(self):
+        assert_raises(
+            sa.exc.ArgumentError,
+            mapper,
+            User, users, properties=util.OrderedDict([
+                ('_user_id', users.c.id),
+                ('id', synonym('_user_id', map_column=True)),
+            ])
+        )
+
+        assert_raises(
+            sa.exc.ArgumentError,
+            mapper,
+            User, users, properties=util.OrderedDict([
+                ('id', synonym('_user_id', map_column=True)),
+                ('_user_id', users.c.id),
+            ])
+        )
+
     @testing.resolve_artifact_names
     def test_comparable(self):
         class extendedproperty(property):