Search code examples
pythongraphqlgraphene-python

Resolver Not Receiving Arguments when Nested


I have a list of classes stored in memory that I am trying to parse through various types. It is referenced through the method get_inventory().

When I call the classes individually, they resolve as I would expect.

But when I try to nest one in the other, the value is returning null.

The code, followed by some examples:

class Account(graphene.ObjectType):

    account_name = graphene.String()
    account_id = graphene.String()

    def resolve_account(
        self, info,
        account_id=None,
        account_name=None
    ):

        inventory = get_inventory()

        result = [Account(
            account_id=i.account_id,
            account_name=i.account_name
        ) for i in inventory if (
            (i.account_id == account_id) or 
            (i.account_name == account_name)
        )]

        if len(result):
            return result[0]
        else:
            return Account()

account = graphene.Field(
    Account, 
    resolver=Account.resolve_account, 
    account_name=graphene.String(default_value=None),
    account_id=graphene.String(default_value=None)
)

class Item(graphene.ObjectType):

    item_name = graphene.String()
    region = graphene.String()
    account = account

    def resolve_item(
        self, info,
        item_name=None
    ):
        inventory = get_inventory()

        result = [Item(
            item_name=i.item_name,
            region=i.region,
            account=Account(
                account_id=i.account_id
            )
        ) for i in inventory if (
            (i.item_name == item_name)
        )]

        if len(result):
            return result[0]
        else:
            return Item()

item = graphene.Field(
    Item, 
    resolver=Item.resolve_item, 
    item_name=graphene.String(default_value=None)
)

class Query(graphene.ObjectType):
    account = account
    item = item

schema = graphene.Schema(query=Query)

Let's assume I have an account foo that has an item bar. The below queries return the fields correctly.

{
  account(accountName:"foo") {
    accountName
    accountId
  }
}

{
  item(itemName: "bar") {
    itemName
    region
  }
}

So if I wanted to find the account that has the item bar, I would think I could query bar and get foo. But it returns the account fields as null.

{
  item(itemName: "bar") {
    itemName
    region
    account {
      accountId
      accountName
    }
  }
}

Recall that as part of resolve_item, I am doing account=Account(account_id=i.account_id) - I would expect this to work.

If I alter the last return statement of resolve_account to the below, accountId always returns yo.

...
else:
    return Account(
        account_id='yo'
    )

So this tells me that my resolver is firing, but the invocation in resolve_item is not passing account_id properly.

What am I doing wrong?


Solution

  • From what I am seeing, it looks like rather than being passed in as an argument, account_id is being stored already as part of account in the ObjectType.

    So if I add the below, I can get to the result that I want.

    account_id = account_id if getattr(self, "account", None) is None else self.account.account_id