Okay, so, this is convoluted and painful.
We have a project where we use a single table inheritence setup to model reports. Each report has email addresses to send it to, when to run it, etc, but is mapped to an individual class for the implementation of what goes into the report.

Now, to save a *load* (we have a hundred or so reports) of duplicate lines of code, I wrote classproperty (yeah, before mixins!) so that we have roughly the following:

        class Report(Base):
            __tablename__ = 'whatever'
            id = Column(Integer, primary_key=True)
            python_type = Column('type', String(50))
            @classproperty
            def __mapper_args__(cls):
                if cls.__name__=='Person':
                    return dict(polymorphic_on=cls.python_type)
                else:
                    return dict(polymorphic_identity=cls.__name__)

        class AReport(Report):
            # other stuff here
            pass

Now, this worked fine in 0.5.8 but http://www.sqlalchemy.org/trac/ticket/1393 and http://www.sqlalchemy.org/trac/ticket/1701 put paid to that :-(

The above is a legitimate case for inheriting __mapper_args__, but I understand the reasons why this is now prohibited.

Okay, so I thought about getting a little creative:

        class ComputedMapperArgs:
            @classproperty
            def __mapper_args__(cls):
                if cls.__name__=='Person':
                    return dict(polymorphic_on=cls.discriminator)
                else:
                    return dict(polymorphic_identity=cls.__name__)

        class Person(Base,ComputedMapperArgs):
            __tablename__ = 'people'
            id = Column(Integer, primary_key=True)
            discriminator = Column('type', String(50))

        class Engineer(Person,ComputedMapperArgs):
            pass

...blows up with:

File "/mnt/Users/chris.withers/sqlalchemy/lib/sqlalchemy/ext/declarative.py", line 722, in __init__
    _as_declarative(cls, classname, cls.__dict__)
File "/mnt/Users/chris.withers/sqlalchemy/lib/sqlalchemy/ext/declarative.py", line 679, in _as_declarative
    ignore_nonexistent_tables=True)
File "/mnt/Users/chris.withers/sqlalchemy/lib/sqlalchemy/sql/util.py", line 205, in join_condition
    "between '%s' and '%s'.%s" % (a.description, b.description, hint))
ArgumentError: Can't find any foreign key relationships between 'people' and 'people'.

As does:

        class ComputedMapperArgs:
            @classproperty
            def __mapper_args__(cls):
                return dict(polymorphic_identity=cls.__name__)

        class Person(Base):
            __tablename__ = 'people'
            id = Column(Integer, primary_key=True)
            discriminator = Column('type', String(50))
            __mapper_args__  = dict(polymorphic_on=discriminator)

        class Engineer(Person,ComputedMapperArgs):
            pass

...*sigh*.

I'll note that the Mixin recipe also produces this behaviour, even in 0.5.8.

Any ideas? I really don't want to have to go through 100 or so classes added back in the __mapper_args__ manually...

Chris


--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to