I have this (simplified) user / group model in one of my projects:
import sqlalchemy
import sqlalchemy.ext.declarative
import sqlalchemy.orm
import sqlalchemy.schema
Base = sqlalchemy.ext.declarative.declarative_base()
class Party(Base):
__tablename__ = 'Party'
type = sqlalchemy.Column(
sqlalchemy.String(1),
nullable=False,
)
name = sqlalchemy.Column(
sqlalchemy.String(255),
primary_key=True,
)
__mapper_args__ = {
'polymorphic_identity': 'S',
'polymorphic_on': type,
}
class User(Party):
__tablename__ = 'User'
name = sqlalchemy.Column(
sqlalchemy.String(255),
sqlalchemy.schema.ForeignKey(Party.name),
primary_key=True,
)
__mapper_args__ = {
'polymorphic_identity': 'U',
}
class Group(Party):
__tablename__ = 'User'
name = sqlalchemy.Column(
sqlalchemy.String(255),
sqlalchemy.schema.ForeignKey(Party.name),
primary_key=True,
)
__mapper_args__ = {
'polymorphic_identity': 'G',
}
class UserGroup(Base):
__tablename__ = 'UserGroup'
user_name = sqlalchemy.Column(
sqlalchemy.String(255),
sqlalchemy.schema.ForeignKey(User.name),
primary_key=True,
)
group_name = sqlalchemy.Column(
sqlalchemy.String(255),
sqlalchemy.schema.ForeignKey(Group.name),
primary_key=True,
)
user = sqlalchemy.orm.relationship(User, backref='user_groups')
I am encountering a problem when trying to load a property user_groups Userin a polymorphic request:
party_poly = sqlalchemy.orm.with_polymorphic(Party, [User, Group])
results = session.query(party_poly) \
.options(sqlalchemy.orm.subqueryload(User.user_groups)) \
.all()
Indicated error:
Cannot find property 'user_groups' for any object specified in this query. Note that the full path from root (Mapper | Party | Party) to the target must be specified.
Through the trial version and error, I received this request to work by changing
party_poly = sqlalchemy.orm.with_polymorphic(Party, [User, Group])
to
party_poly = sqlalchemy.orm.with_polymorphic(Party, [User, Group],
_use_mapper_path=True)
So the question is: can one rely on an undocumented argument argument _use_mapper_path? Does anyone know what he is doing?
Is there a better way to do what I'm trying to do? If there is, I would love to hear it!