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.

Reply via email to