provide a means of resolving single-table subclass-declared column conflicts
this is a pseudopatch illustrating the behavior of a new method
__conflicts__() which allows declared subclasses to have common columns:
diff -r 8719cf3653b9f4209a6d8e774a03cd4c5d579b8b lib/sqlalchemy/ext/declarative.py --- a/lib/sqlalchemy/ext/declarative.py Thu Apr 19 12:31:15 2012 -0400 +++ b/lib/sqlalchemy/ext/declarative.py Fri Apr 20 06:48:32 2012 -0400 @@ -1289,6 +1289,20 @@ "class with no table." ) if c.name in inherited_table.c: + if hasattr(cls, '__conflicts__'): + resolved = cls.__conflicts__( + # need to figure out how to get the + # mapped attribute name here + _get_the_key_for_this_column(c), + inherited_table.c[c.name](c.name), + c) + if resolved is not None and \ + resolved is not inherited_table.c[c.name](c.name): + # make sure this replaces the existing without + # warning + inherited_table.append_column(resolved) + continue + raise exc.ArgumentError( "Column '%s' on class %s conflicts with " "existing column '%s'" %
use case is:
class Person(Base): __tablename__ = 'person' id = Column() class Mixin(object): target_id = Column(ForeignKey()) target = relationship() @classmethod def __conflicts__(cls, key, existing, new): return existing class Engineer(Mixin, Person): """single table inheritance""" class Manager(Mixin, Person): """single table inheritance"""
it has a few tricks to be worked out, namely how to we get at the attribute key there, probably need to search through our_stuff (or do a reverse lookup of our_stuff) to find it.