Python & Graphene: PropertyType fields must be a mapping (dict / OrderedDict)

Viewed 760

I'm building a GraphQL service atop a database that returns information about a matching property. The DB query can be empty, return one or many entries.

The property itself is encapsulated in a corresponding class & type:

class Property(graphene.ObjectType):
   PROPERTY_ID = graphene.Int()
   PROPERTY_TYPE = graphene.String()
   DATE_REPORTED = graphene.String()
   NO_OF_OWNERS = graphene.String()
   OWNER_FULL_NAME = graphene.String()
   ….

class PropertyType(graphene.ObjectType):
  class Meta:
    model = Property   

Extraction from the DB happens through a tiny util that builds a list of properties and returns that list.

def get_properties(address, full_name):
    query = qg.query_properties(address, full_name)
    extract = qm.run_query(query)
    prop_list = []

 for idx, row in extract.iterrows():
    prop_cash = extract.iloc[idx]['CASH_REPORTED']
    prop_id = extract.iloc[idx]['PROPERTY_ID']
    prop_type = extract.iloc[idx]['PROPERTY_TYPE']
    prop_date_rep = extract.iloc[idx]['DATE_REPORTED']
    prop_no_owners = extract.iloc[idx]['NO_OF_OWNERS']
    prop_owner_full_name = extract.iloc[idx]['OWNER_FULL_NAME']
    prop_owner_address = extract.iloc[idx]['OWNER_STREET_1']
    prop_owner_city = extract.iloc[idx]['OWNER_CITY']
    prop_owner_zip = extract.iloc[idx]['OWNER_ZIP']

    prop_list.append(Property(
        CASH_REPORTED=prop_cash,
        PROPERTY_ID=prop_id,
        PROPERTY_TYPE=prop_type,
        DATE_REPORTED=prop_date_rep,
        NO_OF_OWNERS=prop_no_owners,
        OWNER_FULL_NAME=prop_owner_full_name,
        OWNER_ADDRESS=prop_owner_address,
        OWNER_CITY=prop_owner_city,
        OWNER_ZIP=prop_owner_zip
    ))

return prop_list

That code works well and returns a list of properties. When exposing that function as GraphQL with Graphene, I get some troubles when using the following schema: import graphene class Query(graphene.ObjectType): report = graphene.Field(PropertyReport, address=graphene.String(), full_name=graphene.String()) properties = graphene.List(PropertyType, address=graphene.String(), full_name=graphene.String())

async def resolve_report(self, info, address, full_name):
    nr_prop, cash_sum, cash_avg, cash_min, cash_max = await get_report(address, full_name)

    return PropertyReport(
        nr_properties=nr_prop,
        sum_cash_reported=cash_sum,
        avg_cash_reported=cash_avg,
        min_cash_reported=cash_min,
        max_cash_reported=cash_max
    )

async def resolve_properties(self, info, address, full_name):
    props = await get_properties(address=address, full_name=full_name)
    return props
    # return Property.objects.all()


schema = graphene.Schema(query=Query)

The property report resolver, which returns a single object, works as expected as GraphQL endpoint and I can query it with any GraphQL client.

The properties resolver, however, doesn't work and throws the following error:

AssertionError: PropertyType fields must be a mapping (dict / OrderedDict) 
with field names as keys or a function which returns such a mapping.

If I understand the error correctly, it just says it cannot map the object property fields in each object for whatever reason.

I struggle with understanding how Graphene handles collection of objects. The documentation says, just make it list of objects assuming and so I declared properties as a list of properties but for some reason the resolver does not match it.

Do I need two resolvers, one for the object, and one for the list?

I am not exactly sure what's wrong here but I get a sense that I am overlooking something.

Thank you

0 Answers
Related