Warn on duplicate polymorphic_identity

Issue #3262 resolved
Sebastian Bank created an issue

Currently, reuse of a value for polymorphic_identity just overwrites the old mapping. This can lead hard to debug failiures (queried instances having unexpected types):

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import Session
from sqlalchemy.ext.declarative import declarative_base


class Spam(declarative_base()):

    __tablename__ = 'spam'

    id = Column(Integer, primary_key=True)

    kind = Column(String)

    __mapper_args__ = {'polymorphic_on': kind, 'polymorphic_identity': 'spam'}


class Eggs(Spam):

   __tablename__ = 'eggs'

   id = Column(Integer, ForeignKey('spam.id'), primary_key=True)

   __mapper_args__ = {'polymorphic_identity': 'spam'}  # warn here


engine = create_engine('sqlite://')

Spam.metadata.create_all(engine)

session = Session(engine)

session.add(Spam())
session.flush()
spam = session.query(Spam).one()

assert type(spam) is Spam  # fails

Provided there is no use case for overwriting, it would be nice to make the user aware of such misconfiguration at an early development stage.

Comments (5)

  1. Mike Bayer repo owner

    the map is typically empty there; seems like it can only be non-empty if the _polymorphic_map parameter was passed, which I don't even think is used anywhere. i wouldn't worry about it.

  2. Lonnie Lonnie

    My use case for doing this is my code is factored into a base class and a sub class. For unit testing it is useful to insert the base class directly into the database without going through the sub class initializer since this allows us to set up states that are't currently possible with the sub class initializer (legacy states for example). We always want to load the sub class, even when it was created through the base class.

    This has worked without warnings or issues since at least 0.6. I understand the reason this is a warning and agree that it should be one. I just wanted to present what I think is a valid use case.

    I plan to restructure the code to not rely on this abuse of the mappers.

  3. Log in to comment