one polymorphic_on to rule them all

Issue #2238 resolved
Mike Bayer repo owner created an issue

This is how it will work:

# traditional
class MyClass(Base):
    # ...
    type = Column(String)

    __mapper_args__ = {
       'polymorphic_on':type
    }

# callable
class MyClass(Base):
    # ...
    type = Column(String)

    def _discriminator(cls, mapper, context, adapted_row, row, klass):
         if adapted_row[klass.type](klass.type) == 'foo':
              return Bar
         else:
              return MyClass

    __mapper_args__ = {
       'polymorphic_on':_discriminator
    }

# arbitrary
class MyClass(Base):
    # ...
    type = Column(String)

    __mapper_args__ = {
       'polymorphic_on':func.foo_bar(xyz)
    }

# fallback identities
# we use a symbol here in case someone is already
# using '*'
from sqlalchemy.orm import DEFAULT_IDENTITY
class MyClass(Base):
    # ...
    type = Column(String)
    __mapper_args__ = {
       'polymorphic_on':type,
       'polymorphic_identity':DEFAULT_IDENTITY
    }

now to solve the problem of all the old with_polymorphic tests and incompatible polymorphic_ons.

polymorphic_on is unconditionally propagated if there is no built in with_polymorphic selectable, uncondititionally not propagated if there is a with_polymorphic_selectable present. Hoping that rule just works here.

Comments (7)

  1. Mike Bayer reporter

    one serious shortcoming here and maybe a reason to not even go the "python lambda" route is that we can't do any kind of single table row limiting.

  2. Log in to comment