- changed status to resolved
honor non ORM/core constructs from @declared_attr
Issue #2517
resolved
association proxy is one target, could be others, e.g.::
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import declared_attr
metadata = MetaData()
BaseObject = declarative_base(metadata=metadata)
class BaseFilter(BaseObject):
__abstract__ = True
id = Column(Integer(), primary_key=True, autoincrement=True)
filter = Column(UnicodeText(), nullable=False)
@declared_attr
def __tablename__(cls):
return '%s_filter' % cls.parent_tablename
@declared_attr
def parent_id(cls):
return Column(Integer(),
ForeignKey('%s.id' % cls.parent_tablename,
ondelete='CASCADE', onupdate='CASCADE'),
nullable=False, index=True)
def __init__(self, filter, **kw):
super(BaseFilter, self).__init__(filter=filter, **kw)
class FilterA(BaseFilter):
parent_tablename = 'type_a'
class FilterB(BaseFilter):
parent_tablename = 'type_b'
class FilterMixin(object):
@declared_attr
def _filters(cls):
return relationship(cls.filter_class,
cascade='all,delete,delete-orphan')
@declared_attr
def filters(cls):
return association_proxy('_filters', 'filter')
class TypeA(BaseObject, FilterMixin):
__tablename__ = 'type_a'
filter_class = FilterA
id = Column(Integer(), primary_key=True, autoincrement=True)
class TypeB(BaseObject, FilterMixin):
__tablename__ = 'type_b'
filter_class = FilterB
id = Column(Integer(), primary_key=True, autoincrement=True)
engine = create_engine('sqlite://')
metadata.bind = engine
metadata.create_all()
Session = sessionmaker(bind=engine)
session = Session()
session.add(TypeA(filters=[u'foo'](u'foo')))
session.add(TypeB(filters=[u'foo'](u'foo')))
session.flush()
patch:
--- a/lib/sqlalchemy/ext/declarative.py Mon Jun 18 10:06:49 2012 -0400
+++ b/lib/sqlalchemy/ext/declarative.py Wed Jun 20 18:43:38 2012 -0400
@@ -1189,7 +1189,7 @@
cls._decl_class_registry[classname](classname) = cls
our_stuff = util.OrderedDict()
- for k in dict_:
+ for k in list(dict_):
# TODO: improve this ? all dunders ?
if k in ('__table__', '__tablename__', '__mapper_args__'):
@@ -1206,6 +1206,9 @@
"left at the end of the line?" % k)
continue
if not isinstance(value, (Column, MapperProperty)):
+ if not k.startswith('__'):
+ dict_.pop(k)
+ setattr(cls, k, value)
continue
if k == 'metadata':
raise exc.InvalidRequestError(
Comments (2)
-
reporter -
reporter - removed milestone
Removing milestone: 0.8.0b1 (automated comment)
- Log in to comment
656cb6461b264935027580a32ce3820a7d73bd7e