Skip to content

Abstract type 'TemplateItemsORMInterface' must resolve to an Object type at runtime for field 'ItemORM.ItemTemplate'. #233

@bojanstavrikj

Description

@bojanstavrikj

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 snapshot

And 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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    awaiting author responseAwaiting response from issue openerbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions