Skip to content
This repository has been archived by the owner on Jul 8, 2023. It is now read-only.

[Error] "children" lookup was already seen with a different queryset. You may need to adjust the ordering of your lookups. #163

Open
ashleyxue529 opened this issue Jan 18, 2023 · 1 comment

Comments

@ashleyxue529
Copy link

ashleyxue529 commented Jan 18, 2023

I'm seeing the above error when running a mutation. It's just this specific case where I see this, most basic mutations work fine. The model setup looks like this:

@gql.django.type(Config)
class ConfigType(relay.Node):
    items: List["ItemType"]

@gql.django.type(Item)
class ItemType(relay.Node):
    label: auto
    children: List["ItemType"]

Mutation: Essentially deletes all the Items and recursively recreates them again with the new values

@gql.django.input_mutation
    def update_items(
        self,
        info: Info,
        config_id: gql.relay.GlobalID,
        items: Optional[List["ItemType"]],
    ) -> Config:
        try:
            config: Config = config_id.resolve_node(info, ensure_type=Config)

            config.items.all().delete()

            for item in items:
                parent = Item(
                    label=item.label,
                    config=config,
                )
                parent.save()
                update_items_recurse(
                    config=config, item=item, parent=parent
                )

            return cast(
                Brand,
                brand,
            )
        except Exception:
            raise RuntimeError("Unable to update navigation items")

def update_items_recurse(
    config: Config,
    item: ItemInputPartial,
    parent: Item,
):
    children = item.children
    if children is gql.UNSET or len(children) == 0:
        return

    for child in children:
        child_node = Item(label=child.label, parent=parent)
        child_node.save()
        update_items_recurse(
            config=config, item=child, parent=child_node
        )

I'm utilizing the Relay Store on the frontend to auto-update values on the Config object so I'm returning the full Config object in the mutation and re-querying the items field on the Config object on return of the mutation, but something is going wrong with the re-querying part. Maybe because I delete all objects on the config and re-create them?

const updateMutation = graphql`
  mutation ShortcutsCardNavigationItemsUpdateMutation(
    $input: UpdateNavigationItemsInput!
  ) {
    updateNavigationItems(input: $input) {
      ... on ConfigType {
        id
        items {
          label 
          children {
            label
            children { ... etc }
          }  
        }
    }
  }
`;

Hope that makes sense. In the meantime I'm going to try to write a custom resolver for the items field to see if that helps at all.

Update: If this helps, I tested this out instead and I see the same error:

@gql.django.type(Config)
class ConfigType(relay.Node):
    @gql.django.field
    def items(self) -> List["ItemType"]:
        return list(self.items.all())

Am I just doing something wrong in the original setup or is there a bug?

@bellini666
Copy link
Member

What might be happening there is that when you call resolve_node it might be optimizing the result for that field. That's the reason the update mutation disables the optimizer extension while retrieving the object: https://github.com/blb-ventures/strawberry-django-plus/blob/main/strawberry_django_plus/mutations/fields.py#L285

So, because the object already has children prefetched, django gave that error.

We can probably try to do something better here, but for now what you can do to workaround that:

  1. Disable the optimizer extension while resolving the node
  2. Retrieve the object you are returning again from the database, which will cause it to come without the prefetched children

I think one of those should help. But as I said, I'll try to think of a better way to avoid that issue

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants