简体   繁体   中英

SqlAlchemy single table inheritance - use base mapper to load inherited models

I use SqlAlchemy classical mapping to organize my mappers and models. And I want to create a model classes hierarchy. I use the next code:

import sys
from sqlalchemy import Table
from sqlalchemy.orm import mapper
from some_module import BaseClass, child_classes

table = Table('tab1', MetaData(schema='public'),
              Column('id', BigInteger, primary_key=True), 
              Column('discrim', String(64)))

base_mapper = mapper(BaseClass, table)

module = sys.modules[__name__]
for cls in child_classes:
    # Each cls object has a class-level attribute `name`
    submapper = mapper(cls, inherits=base_mapper, local_table=None,
                       polymorphic_on=table.c.discrim,
                       polymorphic_identity=cls.name)
    setattr(module, cls.name + '_mapper', submapper)

And then I want to load models from the DB using the base_mapper .

query = db_session.query(base_mapper)
query = query.filter(base_mapper.mapped_table.c.discrim == 'foo')
print(query.all())

I expect to get an array of Foo class objects, but in the reality I get the BaseClass objects. What am I doing wrong?

Eventually, I found a solution. The main point is to move a polymorphic_on= clause from a subclass mapper to the base class mapper.

# ...
base_mapper = mapper(BaseClass, table, 
                     polymorphic_on=table.c.discrim)
# ...
for cls in child_classes:
    submapper = mapper(cls, inherits=base_mapper, 
                       polymorphic_identity=cls.name)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM