From: Mike Bayer Date: Thu, 12 Jun 2008 03:53:39 +0000 (+0000) Subject: - merged r4841 from 0.4 branch (enable_typechecks lockdown) X-Git-Tag: rel_0_5beta1~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=887c8efc5bebc5904087042b58ab922c1f62091c;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - merged r4841 from 0.4 branch (enable_typechecks lockdown) --- diff --git a/CHANGES b/CHANGES index 4a08007cdf..1b7255e9d3 100644 --- a/CHANGES +++ b/CHANGES @@ -80,6 +80,12 @@ user_defined_state - fixed bug preventing merge() from functioning in conjunction with a comparable_property() + + - the enable_typechecks=False setting on relation() + now only allows subtypes with inheriting mappers. + Totally unrelated types, or subtypes not set up with + mapper inheritance against the target mapper are + still not allowed. - mysql - Added 'CALL' to the list of SQL keywords which return diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py index 251c7ab8b0..ec0bb4d093 100644 --- a/lib/sqlalchemy/orm/dependency.py +++ b/lib/sqlalchemy/orm/dependency.py @@ -107,11 +107,12 @@ class DependencyProcessor(object): raise NotImplementedError() def _verify_canload(self, state): - if not self.enable_typechecks: - return - if state is not None and not self.mapper._canload(state): - raise exc.FlushError("Attempting to flush an item of type %s on collection '%s', which is handled by mapper '%s' and does not load items of that type. Did you mean to use a polymorphic mapper for this relationship ? Set 'enable_typechecks=False' on the relation() to disable this exception. Mismatched typeloading may cause bi-directional relationships (backrefs) to not function properly." % (state.class_, self.prop, self.mapper)) - + if state is not None and not self.mapper._canload(state, allow_subtypes=not self.enable_typechecks): + if self.mapper._canload(state, allow_subtypes=True): + raise exc.FlushError("Attempting to flush an item of type %s on collection '%s', which is not the expected type %s. Configure mapper '%s' to load this subtype polymorphically, or set enable_typechecks=False to allow subtypes. Mismatched typeloading may cause bi-directional relationships (backrefs) to not function properly." % (state.class_, self.prop, self.mapper.class_, self.mapper)) + else: + raise exc.FlushError("Attempting to flush an item of type %s on collection '%s', whose mapper does not inherit from that of %s." % (state.class_, self.prop, self.mapper.class_)) + def _synchronize(self, state, child, associationrow, clearkeys, uowcommit): """Called during a flush to synchronize primary key identifier values between a parent/child object, as well as to an diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 3139ac507c..dd54ed986a 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -826,9 +826,9 @@ class Mapper(object): return self.base_mapper is other.base_mapper - def _canload(self, state): + def _canload(self, state, allow_subtypes): s = self.primary_mapper() - if s.polymorphic_on: + if self.polymorphic_on or allow_subtypes: return _state_mapper(state).isa(s) else: return _state_mapper(state) is s @@ -942,7 +942,6 @@ class Mapper(object): def _primary_key_from_state(self, state): return [self._get_state_attr_by_column(state, column) for column in self.primary_key] - def _get_col_to_prop(self, column): try: return self._columntoproperty[column]