I ran into an interesting bug that is caused by how we calculate the unique key in a NestedFilterableConnectionField:
# Unique dataloader key for context.
data_loader_key = tuple((p for p in info.path if isinstance(p, str)))
The bug occurs when there is a polymorphic field that is represented by a Union and a NestedFilterableConnectionField is queried off of the different Union types. The dataloader_key will not be unique even if the root is a different type
Example Setup (Simplified version but hopefully one can fill in the gaps):
class PrimaryRecord(Base):
id = Column(Integer, primary_key=True, autoincrement=True)
discriminator = Column(String)
references = relationship("Reference", secondary='primary_record_reference', backref="primary_records")
class Reference(Base):
id = Column(Integer, primary_key=True, autoincrement=True)
url = Column(String, nullable=False)
class PrimaryRecordReference(Base):
primary_record_id = Column(Integer, ForeignKey('primary_record.id'), primary_key=True)
reference_id = Column(Integer, ForeignKey('reference.id'), primary_key=True)
class Video(PrimaryRecord):
id = Column(Integer, ForeignKey(PrimaryRecord.id), primary_key=True)
__mapper_args__ = {"polymorphic_identity": "Video", 'polymorphic_load': 'inline'}
title = Column(String, nullable=False)
class Image(PrimaryRecord):
id = Column(Integer, ForeignKey(PrimaryRecord.id), primary_key=True)
__mapper_args__ = {"polymorphic_identity": "Image", 'polymorphic_load': 'inline'}
name = Column(String)
query { records { edges {
node {
__typename
... on Video {
id
title
references { edges { node { id } } }
}
... on Image {
id
name
references { edges { node { id } } }
}
}
} } }
When using this setup, the data_loader_key for both Image and Video references is 'records', 'edges', 'node', 'references' even though the ModelLoader's parent_model needs to be different (a reference attached to a Video cannot be found when the parent_model is an Image)
I fixed this by simply adding the class name to the unique key, so different parent classes have different data loaders:
data_loader_key = tuple((p for p in info.path + [root.__class__.__name__] if isinstance(p, str)))
Not sure if it's worth fixing or if there's a better way to do it, but documenting this just in case someone else somehow runs into this particular edge case.
I ran into an interesting bug that is caused by how we calculate the unique key in a
NestedFilterableConnectionField
:The bug occurs when there is a polymorphic field that is represented by a Union and a
NestedFilterableConnectionField
is queried off of the different Union types. The dataloader_key will not be unique even if the root is a different typeExample Setup (Simplified version but hopefully one can fill in the gaps):
Union classes:
Sample query:
When using this setup, the
data_loader_key
for both Image and Video references is'records', 'edges', 'node', 'references'
even though theModelLoader
'sparent_model
needs to be different (a reference attached to a Video cannot be found when theparent_model
is an Image)I fixed this by simply adding the class name to the unique key, so different parent classes have different data loaders:
Not sure if it's worth fixing or if there's a better way to do it, but documenting this just in case someone else somehow runs into this particular edge case.