On Oct 21, 2010, at 2:39 PM, oystein wrote:
> Hi all,
>
> I am using declarative to model an existing object hierarchy where
> there is an
> abstract part that i model as an hierarchy of mixins and a concrete
> part where
> i use joined-table inheritance.
>
> I have a problem when there is attributes with the same name, one
> overriding
> the other, in the abstract mixin hierarchy. Maybe I am doing something
> wrong
> so suggestions for how to implement this is most welcome.
Your patch is completely correct in that an attribute on a mixin should take
precedence that of super-class mixins. The story is a little different for
attributes on mapped classes, but that's not an issue here. The patch leaves
existing tests unaffected, and is committed in r67a7868cfba1 along with a new
test...thanks !
>
> Sample code:
>
> import unittest
> from sqlalchemy.orm import sessionmaker
> from sqlalchemy import create_engine
> from sqlalchemy.ext.declarative import declarative_base
> from sqlalchemy import Column, String, Integer, Boolean
>
> Base = declarative_base()
>
> class AbstractA(object):
> AttrA = Column(String(50))
> def __init__(self, AttrA="AttrA"):
> self.AttrA = AttrA
>
> class AbstractB(AbstractA):
> AttrA = Column(String(50), primary_key=True)
> def __init__(self, AttrA, **kwargs):
> AbstractA.__init__(self, **kwargs)
> self.AttrA = AttrA
>
> class Concrete(Base, AbstractB):
> __tablename__ = 'Concrete'
> AttrB = Column(Boolean)
> def __init__(self, AttrB, **kwargs):
> AbstractB.__init__(self, **kwargs)
> self.AttrB = AttrB
>
>
> class TestAttributeOverriding(unittest.TestCase):
>
> def testAttributeOverriding(self):
> concrete = Concrete(AttrB = False, AttrA="0")
> self.session.add(concrete)
> self.session.commit()
> assert len(self.session.query(Concrete).all()) == 1
>
> def setUp(self):
> self.engine = create_engine('sqlite:///:memory:', echo = True)
> Session = sessionmaker(bind = self.engine)
> self.session = Session()
> self.metadata = Base.metadata
> self.metadata.create_all(self.engine)
>
> def tearDown(self):
> self.metadata.drop_all(self.engine)
> self.session.close()
>
>
>
> This would fail with "could not assemble any primary key columns for
> mapped
> table" unless i apply the small patch below, which makes it work as i
> would
> expect (although i don't know if this is how it is intended to be):
>
> --- /usr/lib/python2.6/site-packages/sqlalchemy/ext/
> declarative.py
> 2010-09-07 19:05:34.000000000 +0200
> +++ lib/python2.6/site-packages/SQLAlchemy-0.6.4-
> py2.6.egg/sqlalchemy/ext/declarative.py 2010-10-21
> 19:58:15.863671633
> +0200
> @@ -936,11 +936,13 @@
> '__table__' in dict_ and
> name in dict_['__table__'].c
> ):
> - potential_columns[name] = \
> - column_copies[obj] = \
> - obj.copy()
> - column_copies[obj]._creation_order = \
> - obj._creation_order
> + if name not in potential_columns:
> + potential_columns[name] = \
> + column_copies[obj] = \
> + obj.copy()
> + column_copies[obj]._creation_order =
> \
> + obj._creation_order
> +
> elif isinstance(obj, MapperProperty):
> raise exceptions.InvalidRequestError(
> "Mapper properties (i.e. deferred,"
>
> ---
>
> Oystein
>
> --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/sqlalchemy?hl=en.
>
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.