[BUG] Document subclasses are cast to parent class in query results
See original GitHub issueI know I’m missing something. Given a model with multiple document types in a collection:
class AModel(Document):
meta = {'allow_inheritance': True}
a_field = StringField()
class ASubModel(AModel):
a_sub_field = StringField()
I can construct a schema and query:
class A(MongoengineObjectType):
class Meta:
model = AModel
interfaces = (Node,)
class ASub(A):
class Meta:
model = ASubModel
interfaces = (Node,)
class Query(graphene.ObjectType):
node = Node.Field()
all_a = MongoengineConnectionField(A)
If I run the allA
query, I get back all the documents as expected, but I can’t access ASub
’s fields because the returned type is A
, not ASub
, even though the class is identified as A.ASub
. E.g.,:
{
"data": {
"allA": {
"edges": [
{
"node": {
"id": "VGFyZ2V0OjVjZTVmOTMwMjRmN2NhMGJmMjZlNzZmMQ==",
"Cls": "A.ASub",
"__typename": "A"
}
}
]
}
}
Attempting to resolve ASub.a_sub_field
results in an error.
Inline fragment doesn’t work either:
{
"errors": [
{
"message": "Fragment cannot be spread here as objects of type A can never be of type ASub",
"locations": [
{
"line": 8,
"column": 9
}
]
}
]
}
I’m clearly doing something wrong, but I don’t know what.
Issue Analytics
- State:
- Created 4 years ago
- Comments:5
Top Results From Across the Web
Can Hibernate Criteria query for subclasses using Restrictions ...
I would like to use the following Criteria query but this results in a ClassCastException since Class cannot be cast to String ....
Read more >Java static code analysis: Classes should not access their ...
Classes should not access their own subclasses during initialization ... When a parent class references a member of a subclass during its own...
Read more >FindBugs Bug Descriptions - SourceForge
This class defines a compareTo(...) method but inherits its equals() method from java.lang.Object . Generally, the value of compareTo should ...
Read more >Inheritance — What your mother never told you, C++ FAQ
Should a derived class redefine (“override”) a member function that is non- virtual in a base class? What's the meaning of, Warning: Derived::f(char)...
Read more >Inheritance in PowerShell Classes - SAPIEN Information Center
So, the AnyGlass class inherits from its parent and grandparent classes — its entire ancestry — just like people do. Add Members to...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Yes, but…if I add a new Document subclass,
Then I have a different problem.
I could use a union, but even that makes me unhappy since I still have to modify the Query class every time I extend the data model. Further, it seems like it takes me away from Relay’s interface, which I’d rather not do.
Using the examples above, mongoengine returns the subclass when fetching on the parent class, which is IMHO correct behavior:
However,
MongoengineConnectionField
descends fromgraphene.Field
, which adopts the named class as the only possible type. As a result, when the query is run returned results are being cast toMongoengineConnectionField._type
, which is the parent class in this example. The casting works because of inheritance, but it’s unexpected behavior when you’re using a mongo backend.I don’t think the other graphene backends won’t have this issue.
IMHO this is a bug. Document subclassing is a key mongo feature, so graphene_mongo should support it. I think the right way is to override graphene’s behavior here and set
__typename
to the returned object’s class, with an assertion that the returned object is a subclass ofMongoengineConnectionField._type
.I think this would allow inline fragments to access fields on each subclass in a way compatible with mongo.