diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-07-20 18:23:44 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-07-20 18:23:44 +0000 |
| commit | 419753f59b6fa68ae282b5a75ad3b3a3b5f91c50 (patch) | |
| tree | d60af45c5135ed252ed06e9e2765295aeaabd0b2 /lib | |
| parent | a4781e4d76c6b1bfb8ae5345c2e09ae35045d8e6 (diff) | |
| download | sqlalchemy-419753f59b6fa68ae282b5a75ad3b3a3b5f91c50.tar.gz | |
- An inheriting class can now override an attribute
inherited from the base class with a plain descriptor,
or exclude an inherited attribute via the
include_properties/exclude_properties collections.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 43 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 2 |
2 files changed, 34 insertions, 11 deletions
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index e8bae46a4..f313a09ee 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -220,6 +220,9 @@ class Mapper(object): o = o or bool(mapper.delete_orphans) return o + def has_property(self, key): + return key in self.__props + def get_property(self, key, resolve_synonyms=False, raiseerr=True): """return a MapperProperty associated with the given key.""" @@ -636,6 +639,31 @@ class Mapper(object): return getattr(getattr(cls, clskey), key) + def _should_exclude(self, name): + """determine whether a particular property should be implicitly present on the class. + + This occurs when properties are propagated from an inherited class, or are + applied from the columns present in the mapped table. + + """ + # check for an existing descriptor + if isinstance( + getattr(self.class_, name, None), + property): + return True + + if (self.include_properties is not None and + name not in self.include_properties): + self.__log("not including property %s" % (name)) + return True + + if (self.exclude_properties is not None and + name in self.exclude_properties): + self.__log("excluding property %s" % (name)) + return True + + return False + def __compile_properties(self): # object attribute names mapped to MapperProperty objects @@ -654,7 +682,7 @@ class Mapper(object): # pull properties from the inherited mapper if any. if self.inherits: for key, prop in self.inherits.__props.iteritems(): - if key not in self.__props: + if key not in self.__props and not self._should_exclude(key): self._adapt_inherited_property(key, prop) # create properties for each column in the mapped table, @@ -662,15 +690,8 @@ class Mapper(object): for column in self.mapped_table.columns: if column in self._columntoproperty: continue - - if (self.include_properties is not None and - column.key not in self.include_properties): - self.__log("not including property %s" % (column.key)) - continue - - if (self.exclude_properties is not None and - column.key in self.exclude_properties): - self.__log("excluding property %s" % (column.key)) + + if self._should_exclude(column.key): continue column_key = (self.column_prefix or '') + column.key @@ -687,6 +708,8 @@ class Mapper(object): # in the 'with_polymorphic' selectable but we need it for the base mapper if self.polymorphic_on and self.polymorphic_on not in self._columntoproperty: col = self.mapped_table.corresponding_column(self.polymorphic_on) or self.polymorphic_on + if self._should_exclude(col.key): + raise sa_exc.InvalidRequestError("Cannot exclude or override the discriminator column %r" % col.key) self._compile_property(col.key, ColumnProperty(col), init=False, setparent=True) def _adapt_inherited_property(self, key, prop): diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 7eecc3320..64162fecb 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -24,7 +24,7 @@ class DefaultColumnLoader(LoaderStrategy): self.logger.info("%s register managed attribute" % self) for mapper in self.parent.polymorphic_iterator(): - if mapper is self.parent or not mapper.concrete: + if (mapper is self.parent or not mapper.concrete) and mapper.has_property(self.key): sessionlib.register_attribute( mapper.class_, self.key, |
