abc inheritance broken

Issue #795 resolved
Mike Bayer repo owner created an issue
from sqlalchemy import *
from sqlalchemy.orm import *

import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)

metadata = MetaData('sqlite://')

a = Table('a', metadata,
          Column('id', Integer, primary_key=True),
          Column('type', String(20), nullable=False),
          Column('name', String(20))
          )

b = Table('b', metadata,
          Column('id', Integer, ForeignKey('a.id'), primary_key=True),
          Column('bname', String(20))
          )

c = Table('c', metadata,
          Column('id', Integer, ForeignKey('b.id'), primary_key=True)
          )

metadata.create_all()

class A(object):
    pass

class B(A):
    pass

class C(B):
    pass

mapper(A, a, polymorphic_on=a.c.type, polymorphic_identity='a')
mapper(B, b, inherits=A, polymorphic_identity='b')
mapper(C, c, inherits=B, polymorphic_identity='c')

session = create_session()

for x in range(1, 3):
    objb = B()
    objb.name = x
    objb.bname = x
    session.save(objb)

    objc = C()
    objc.name = x
    objc.bname = x
    session.save(objc)

session.flush()
session.clear()

for obj in session.query(A).all():
    print obj, obj.name, obj.bname
    assert obj.name == obj.bname

Comments (2)

  1. Mike Bayer reporter

    the construction of the secondary (immediate or deferred) SELECT statement used for the polymorphic load needed to take into account the full list of mappers from the endpoint to the original querying mapper in order to construct the appropriate WHERE criterion; in the case of a query against A loading a C, this is mappers B and C. in the case of a query against B loading a C, its just C. note this bug does not exist with "union" or "join" style polymorphic loading which is what our existing abc_inheritance.py test tests (that test actually requires joined style since the tables don't have a 'type' column ! ). 0dde728591cb083e351cf1ff1998aaf1883ab7a1.

  2. Log in to comment