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".
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
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:
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):