-
-
Notifications
You must be signed in to change notification settings - Fork 34
Description
Hello all, I have been stuck on this problem and can't figure out how to resolve it.
I am using the StrawberrySQLAlchemyMapper to create my strawberry classes based on my ORM classes. It all works fine until I reach a table which is polymorphic.
These are my ORM classes:
class PurchaseORM(BaseORM):
__tablename__ = "purchases"
id: Mapped[uuid] = mapped_column(nullable=False, primary_key=True)
templateId: Mapped[uuid] = mapped_column(nullable=False)
createdBy: Mapped[str] = mapped_column(nullable=False)
creationDate: Mapped[datetime]
Items: Mapped[List["ItemORM"]] = relationship( "ItemORM", back_populates='purchase' )
class ItemORM(BaseORM):
__tablename__ = 'items'
id: Mapped[uuid] = mapped_column(nullable=False, primary_key=True)
purchaseId: Mapped[uuid] = mapped_column(ForeignKey("purchases.id"), nullable=False)
templateItemId: Mapped[uuid] = mapped_column( nullable=False)
status: Mapped[str] = mapped_column(nullable=True)
updatedAt: Mapped[datetime] = mapped_column(nullable=False, default=func.current_timestamp(), onupdate=func.current_timestamp())
createdAt: Mapped[datetime] = mapped_column(nullable=False, default=func.current_timestamp())
purchase: Mapped["PurchaseORM"] = relationship("SnapshotContext", back_populates='Items')
itemTemplate: Mapped["TemplateItemsORM"] = relationship("TemplateItemsORM", back_populates='Item')
class TemplateItemsORM(BaseORM):
__tablename__ = 'template_items'
id: Mapped[uuid] = mapped_column(ForeignKey("items.templateItemId"), nullable=False, primary_key=True)
name: Mapped[str]
type: Mapped[str]
description: Mapped[str]
Item: Mapped["ItemORM"] = relationship("ItemORM", back_populates='itemTemplate')
__mapper_args__ = {
'polymorphic_on': 'type',
'polymorphic_identity': 'TemplateItemsORM',
}
class alarmTemplateItemORM(TemplateItemsORM):
__mapper_args__ = {
'polymorphic_identity': 'alarm',
}
class sensorTemplateItemORM(TemplateItemsORM):
__mapper_args__ = {
'polymorphic_identity': 'sensor',
}Then I create the related strawberry classes using strawberry StrawberrySQLAlchemyMapper as follows:
strawberry_sqlalchemy_mapper = StrawberrySQLAlchemyMapper()
@strawberry.input
class PurchaseInput:
id: str
@strawberry_sqlalchemy_mapper.type(PurchaseORM)
class Purchase:
pass
@strawberry_sqlalchemy_mapper.type(ItemORM)
class Item:
pass
@strawberry_sqlalchemy_mapper.type(TemplateItemsORM)
class TemplateItem:
pass
@strawberry_sqlalchemy_mapper.type(alarmTemplateItemsORM)
class alarmTemplateItems:
pass
@strawberry_sqlalchemy_mapper.type(sensorTemplateItemsORM)
class sensorTemplateItems:
pass
@strawberry.type
class Query:
@strawberry.field
def getPurchaseById(self, filter: PurchaseInput) -> Purchase:
session = bootstrap.bootstrapDBEngine(config.get('db_config', {}))
with session() as session:
pm = with_polymorphic(TemplateItemsORM, [alarmTemplateItemsORM, sensorTemplateItemsORM])
sql = select(PurchaseORM).filter(PurchaseORM.id==filter.id).options(
joinedload(PurchaseORM.Items).options(joinedload(
TemplateItemsORM.itemTemplate.of_type(pm)
)),
)
snapshot = session.execute(sql).scalars().first()
return snapshotAnd then the query I execute in the playground is the following:
query MyQuery { getPurchaseById(filter: {id: "334dbb48-31b8-4d18-a9c0-123d7be7a17c"}) { id createdBy Items { edges { node { id status TemplateItem { id name description } } } } } }
I get the following error and I cannot figure out how to resolve it:
graphql.error.graphql_error.GraphQLError: Abstract type 'TemplateItemsORMInterface' must resolve to an Object type at runtime for field 'ItemORM.ItemTemplate'. Either the 'TemplateItemsORMInterface' type should provide a 'resolve_type' function or each possible type should provide an 'is_type_of' function.
I have tested the query inside getPurchaseById, and the sqlalchemy query returns the what I am expecting.
I havent been able to figure out where and how to define these resolve_type or is_type_of functions. Any help is aprpeciated!