From: Mike Bayer Date: Tue, 28 Sep 2010 16:43:36 +0000 (-0400) Subject: - Fixed bug whereby columns on a mixin wouldn't propagate X-Git-Tag: rel_0_6_5~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ec3e6c7dc2c03849b140c17e17e1efdc2f932a4a;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Fixed bug whereby columns on a mixin wouldn't propagate correctly to a single-table inheritance scheme where the attribute name is different than that of the column. [ticket:1930]. Note [ticket:1931] which is the same issue for joined inh, not yet resolved. --- diff --git a/CHANGES b/CHANGES index d43732e468..38fd7443bf 100644 --- a/CHANGES +++ b/CHANGES @@ -143,7 +143,13 @@ CHANGES Same thing, but moving there since it is more of a "marker" that's specific to declararative, not just an attribute technique. [ticket:1915] - + + - Fixed bug whereby columns on a mixin wouldn't propagate + correctly to a single-table inheritance scheme where + the attribute name is different than that of the column. + [ticket:1930]. Note [ticket:1931] which is the same + issue for joined inh, not yet resolved. + - engine - Fixed a regression in 0.6.4 whereby the change that diff --git a/lib/sqlalchemy/ext/declarative.py b/lib/sqlalchemy/ext/declarative.py index cbda848e80..211b6724a7 100755 --- a/lib/sqlalchemy/ext/declarative.py +++ b/lib/sqlalchemy/ext/declarative.py @@ -938,7 +938,10 @@ def _as_declarative(cls, classname, dict_): "on declarative mixin classes. ") if name not in dict_ and not ( '__table__' in dict_ and - name in dict_['__table__'].c + # TODO: coverage here when obj.name is not + # None and obj.name != name and obj.name in + # table.c + (obj.name or name) in dict_['__table__'].c ): potential_columns[name] = \ column_copies[obj] = \ @@ -960,7 +963,7 @@ def _as_declarative(cls, classname, dict_): # apply inherited columns as we should for k, v in potential_columns.items(): - if tablename or k not in parent_columns: + if tablename or (v.name or k) not in parent_columns: dict_[k] = v if inherited_table_args and not tablename: @@ -1087,7 +1090,7 @@ def _as_declarative(cls, classname, dict_): "Can't place __table_args__ on an inherited class " "with no table." ) - + # add any columns declared here to the inherited table. for c in cols: if c.primary_key: diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index b56de5f05d..ddaf62c7f1 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -399,7 +399,7 @@ class AttributeImpl(object): # Return a new, empty value return self.initialize(state, dict_) - + def append(self, state, dict_, value, initiator, passive=PASSIVE_OFF): self.set(state, dict_, value, initiator, passive=passive) diff --git a/test/ext/test_declarative.py b/test/ext/test_declarative.py index 81e6829e43..1b3e72fc7f 100644 --- a/test/ext/test_declarative.py +++ b/test/ext/test_declarative.py @@ -2304,6 +2304,37 @@ class DeclarativeMixinTest(DeclarativeTestBase): assert Specific.__table__ is General.__table__ eq_(General.__table__.kwargs, {'mysql_engine': 'InnoDB'}) + def test_columns_single_table_inheritance(self): + class MyMixin(object): + foo = Column('foo', Integer) + bar = Column('bar_newname', Integer) + + class General(Base, MyMixin): + __tablename__ = 'test' + id = Column(Integer, primary_key=True) + type_ = Column(String(50)) + __mapper__args = {'polymorphic_on': type_} + + class Specific(General): + __mapper_args__ = {'polymorphic_identity': 'specific'} + + @testing.fails_if(lambda: True, "Unhandled declarative use case") + def test_columns_joined_table_inheritance(self): + class MyMixin(object): + foo = Column('foo', Integer) + bar = Column('bar_newname', Integer) + + class General(Base, MyMixin): + __tablename__ = 'test' + id = Column(Integer, primary_key=True) + type_ = Column(String(50)) + __mapper__args = {'polymorphic_on': type_} + + class Specific(General): + __tablename__ = 'sub' + id = Column(Integer, ForeignKey('test.id'), primary_key=True) + __mapper_args__ = {'polymorphic_identity': 'specific'} + def test_table_args_overridden(self): class MyMixin: