- changed status to resolved
declarative classproperty...still broken (need __mapper_args__ etc. to work from non-mixins)
Issue #1922
resolved
we ignore __mapper_args__
, __table_args__
from the base when processing the subclass:
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.util import classproperty
Base = declarative_base()
class Car(Base):
__tablename__ = 'car'
id = Column(Integer, primary_key=True)
class_name = Column(Unicode(128), nullable=False)
@classproperty
def __mapper_args__(cls):
if cls.__name__ == "Car":
return {"polymorphic_on":cls.class_name, "polymorphic_identity":"Car", "with_polymorphic":"*"}
else:
return {"polymorphic_identity":cls.__name__}
class Ferrari(Car):
pass
# fails
assert class_mapper(Ferrari).polymorphic_identity == "Ferrari"
Since we are going with the notion that @classproperty
is special to declarative (and replacing with @mapperproperty
in 0.7), this patch adds that approach to the mapper and table elements:
diff -r c5c8cdf3b4d7dc456cfef29ea04b2b7300060c7a lib/sqlalchemy/ext/declarative.py
--- a/lib/sqlalchemy/ext/declarative.py Sat Sep 18 13:34:04 2010 -0400
+++ b/lib/sqlalchemy/ext/declarative.py Mon Sep 20 10:43:34 2010 -0400
@@ -908,51 +908,63 @@
parent_columns = ()
for base in cls.__mro__:
- if _is_mapped_class(base):
+ class_mapped = _is_mapped_class(base)
+ if class_mapped:
parent_columns = base.__table__.c.keys()
- else:
- for name,obj in vars(base).items():
- if name == '__mapper_args__':
- if not mapper_args:
- mapper_args = cls.__mapper_args__
- elif name == '__tablename__':
- if not tablename:
- tablename = cls.__tablename__
- elif name == '__table_args__':
- if not table_args:
- table_args = cls.__table_args__
- if base is not cls:
- inherited_table_args = True
- elif base is not cls:
- # we're a mixin.
-
- if isinstance(obj, Column):
- if obj.foreign_keys:
- raise exceptions.InvalidRequestError(
- "Columns with foreign keys to other columns "
- "must be declared as @classproperty callables "
- "on declarative mixin classes. ")
- if name not in dict_ and not (
- '__table__' in dict_ and
- name in dict_['__table__']('__table__').c
- ):
- potential_columns[name](name) = \
- column_copies[obj](obj) = \
- obj.copy()
- column_copies[obj](obj)._creation_order = \
- obj._creation_order
- elif isinstance(obj, MapperProperty):
+
+ for name,obj in vars(base).items():
+ if name == '__mapper_args__':
+ if not mapper_args and (
+ not class_mapped or
+ isinstance(obj, util.classproperty)
+ ):
+ mapper_args = cls.__mapper_args__
+ elif name == '__tablename__':
+ if not tablename and (
+ not class_mapped or
+ isinstance(obj, util.classproperty)
+ ):
+ tablename = cls.__tablename__
+ elif name == '__table_args__':
+ if not table_args and (
+ not class_mapped or
+ isinstance(obj, util.classproperty)
+ ):
+ table_args = cls.__table_args__
+ if base is not cls:
+ inherited_table_args = True
+ elif class_mapped:
+ continue
+ elif base is not cls:
+ # we're a mixin.
+
+ if isinstance(obj, Column):
+ if obj.foreign_keys:
raise exceptions.InvalidRequestError(
- "Mapper properties (i.e. deferred,"
- "column_property(), relationship(), etc.) must "
- "be declared as @classproperty callables "
- "on declarative mixin classes.")
- elif isinstance(obj, util.classproperty):
- dict_[name](name) = ret = \
- column_copies[obj](obj) = getattr(cls, name)
- if isinstance(ret, (Column, MapperProperty)) and \
- ret.doc is None:
- ret.doc = obj.__doc__
+ "Columns with foreign keys to other columns "
+ "must be declared as @classproperty callables "
+ "on declarative mixin classes. ")
+ if name not in dict_ and not (
+ '__table__' in dict_ and
+ name in dict_['__table__']('__table__').c
+ ):
+ potential_columns[name](name) = \
+ column_copies[obj](obj) = \
+ obj.copy()
+ column_copies[obj](obj)._creation_order = \
+ obj._creation_order
+ elif isinstance(obj, MapperProperty):
+ raise exceptions.InvalidRequestError(
+ "Mapper properties (i.e. deferred,"
+ "column_property(), relationship(), etc.) must "
+ "be declared as @classproperty callables "
+ "on declarative mixin classes.")
+ elif isinstance(obj, util.classproperty):
+ dict_[name](name) = ret = \
+ column_copies[obj](obj) = getattr(cls, name)
+ if isinstance(ret, (Column, MapperProperty)) and \
+ ret.doc is None:
+ ret.doc = obj.__doc__
# apply inherited columns as we should
for k, v in potential_columns.items():
Comments (2)
-
reporter -
reporter - removed milestone
Removing milestone: 0.6.5 (automated comment)
- Log in to comment
4fbd16e045cc0daed754f2c4f9732ba1ac128205