summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-07-20 18:23:44 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-07-20 18:23:44 +0000
commit419753f59b6fa68ae282b5a75ad3b3a3b5f91c50 (patch)
treed60af45c5135ed252ed06e9e2765295aeaabd0b2 /lib
parenta4781e4d76c6b1bfb8ae5345c2e09ae35045d8e6 (diff)
downloadsqlalchemy-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.py43
-rw-r--r--lib/sqlalchemy/orm/strategies.py2
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,