Graphene Python class 不认识自己

Graphene Python class doesn't recognize self

我有以下 Python 实现石墨烯的模块。

import graphene
import json
import psycopg2

connection = psycopg2.connect(user='postgres', password='xxxxx', host='127.0.0.1', port='5432', database='xxxx')
cursor = connection.cursor()

class Entity(graphene.ObjectType):
    name = graphene.String()

class Query(graphene.ObjectType):
    entity_relationships = graphene.List(Entity, entity=graphene.String())
    postgresql_version = graphene.String
    path = graphene.String(name=graphene.String(), path=graphene.String(), accumulate=graphene.String(), depth=graphene.Int())

    def get_foreign_relationships(self, entity):
        cursor.execute('''
            SELECT 
                tc.table_schema, tc.constraint_name, tc.table_name, kcu.column_name, ccu.table_schema AS foreign_table_schema, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name 
            FROM information_schema.table_constraints AS tc 
            JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name
            AND tc.table_schema = kcu.table_schema
            JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name
            AND ccu.table_schema = tc.table_schema
            WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='{}';'''.format(entity))
        result = cursor.fetchall()
        result_array = []
        
        for record in result:
            new_entity = Entity(name=record[5])
            result_array.append(new_entity)

        return result_array

    def is_relationship(self, referencing, referenced):
        foreign_relationships = self.get_foreign_relationships(referencing)

        if referenced in list(map(lambda table: relationship[5], foreign_relationships)):
            return True
        else:
            return False

    def traverse(self, entities, direction):
        for i in range(len(entities)):
            if i > 0 and i < len(entities)-1:
                if not self.is_relationship(entities[i], entities[i-1]):
                    raise "entity {} has no relation with entity {}".format(entities[i], entities[i-1])

        return True

    def validate_path(self, path):
        entities = path.split('/')
        
        self.traverse(entities)

        return True

    def resolve_path(self, info, name, path, accumulate, depth):
        if self.validate_path(path):
            return "Éste método regresará los datos anidados para el camino '{}'".format(path)

    def resolve_entity_relationships(self, info, entity):
        result_array = self.get_foreign_relationships(entity)

        return result_array

    def resolve_postgresql_version(self, info):
        cursor.execute("SELECT version();")
        record = cursor.fetchone()
        return record

def execute_query(query_to_execute):
    queries = {
        'postgresqlVersion': '''
            {
                postgresqlVersion
            }
        ''',
        'entityRelationships': '''
            {
                entityRelationships (entity: "inventory_productitem") {
                    name
                }
            }
        ''',
        'path': '''
            {
                path(name: "Ventas", path: "inventory_family/inventory_product/inventory_sale", accumulate: "_calculate(amount*price)", depth: 1)
            }
        '''
    }

    schema = graphene.Schema(query=Query)

    result = schema.execute(queries[query_to_execute])

    dict_result = dict(result.data.items())
    print(json.dumps(dict_result, indent=2))

execute_query('path')

问题是调用 class 的其他方法的解析器会引发此错误:

Traceback (most recent call last):
  File "/Users/hugovillalobos/Documents/Code/agrowareproject/backend/AgrowareVenv/lib/python3.7/site-packages/graphql/execution/executor.py", line 452, in resolve_or_error
    return executor.execute(resolve_fn, source, info, **args)
  File "/Users/hugovillalobos/Documents/Code/agrowareproject/backend/AgrowareVenv/lib/python3.7/site-packages/graphql/execution/executors/sync.py", line 16, in execute
    return fn(*args, **kwargs)
  File "query.py", line 59, in resolve_path
    if self.validate_path(path):
graphql.error.located_error.GraphQLLocatedError: 'NoneType' object has no attribute 'validate_path'

出现错误的那一行是: if self.validate_path(path):

我不知道为什么,如果方法 validate_path() 与调用它的方法在同一个 class 中。

这是因为Graphene考虑所有resolver方法都是staticmethods

来自doc,

Sometimes this argument will be named self in Graphene code, but this can be misleading due to Implicit staticmethod while executing queries in Graphene.

因此,您必须按如下方式重新安排代码,

<b>def validate_path(path):
    # do something
    return True  # ot False depends on your evaluation</b>


class Query(graphene.ObjectType):
    path = graphene.String(
        name=graphene.String(),
        path=graphene.String(),
        accumulate=graphene.String(),
        depth=graphene.Int()
    )

    <b>@staticmethod</b>
    def resolve_path(<b>parent</b>, info, name, path, accumulate, depth):
        if <b>validate_path(path)</b>:
            return "Validated path"
        return "Path Not Valid"