art1415926535 / graphene-sqlalchemy-filter

Filters for Graphene SQLAlchemy integration
https://pypi.org/project/graphene-sqlalchemy-filter/
MIT License
118 stars 34 forks source link

can not have a field named `type` with `in` filter #28

Closed sreerajkksd closed 3 years ago

sreerajkksd commented 4 years ago

I have a field named type and adding that in filterset fields give the following error to when creating the schema.

Exception has occurred: AttributeError
type object 'function' has no attribute 'name'

eg:

class SampleFilter(FilterSet):
    class Meta:
        model = SampleModel
        fields = {
            'name': [...],
            'type': [...],
        }

class Query(graphene.ObjectType):
   node = graphene.relay.Node.Field()
   all_samples = FilterableConnectionField(SampleSchemaObject.connection, filters=SampleFilter())

schema = graphene.Schema(query=Query)
art1415926535 commented 4 years ago

Can you provide stack trace? I added type to example and everything works fine.

image

sreerajkksd commented 4 years ago

That's strange.

This is the complete stack trace.

  File "/home/karicher/application/schema.py", line 92, in <module>
    schema = graphene.Schema(query=Query, mutation=Mutation)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/schema.py", line 78, in __init__
    self.build_typemap()
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/schema.py", line 168, in build_typemap
    initial_types, auto_camelcase=self.auto_camelcase, schema=self
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 80, in __init__
    super(TypeMap, self).__init__(types)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphql/type/typemap.py", line 31, in __init__
    self.update(reduce(self.reducer, types, OrderedDict()))  # type: ignore
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 88, in reducer
    return self.graphene_reducer(map, type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 117, in graphene_reducer
    return GraphQLTypeMap.reducer(map, internal_type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphql/type/typemap.py", line 109, in reducer
    field_map = type_.fields
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphql/pyutils/cached_property.py", line 22, in __get__
    value = obj.__dict__[self.func.__name__] = self.func(obj)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphql/type/definition.py", line 198, in fields
    return define_field_map(self, self._fields)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphql/type/definition.py", line 212, in define_field_map
    field_map = field_map()
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 287, in construct_fields_for_type
    map = self.reducer(map, arg.type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 88, in reducer
    return self.graphene_reducer(map, type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 117, in graphene_reducer
    return GraphQLTypeMap.reducer(map, internal_type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphql/type/typemap.py", line 109, in reducer
    field_map = type_.fields
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphql/pyutils/cached_property.py", line 22, in __get__
    value = obj.__dict__[self.func.__name__] = self.func(obj)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphql/type/definition.py", line 641, in fields
    return self._define_field_map()
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphql/type/definition.py", line 646, in _define_field_map
    fields = self._fields()
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 275, in construct_fields_for_type
    map = self.reducer(map, field.type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 88, in reducer
    return self.graphene_reducer(map, type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 93, in graphene_reducer
    return self.reducer(map, type.of_type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 88, in reducer
    return self.graphene_reducer(map, type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 93, in graphene_reducer
    return self.reducer(map, type.of_type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphene/types/typemap.py", line 89, in reducer
    return GraphQLTypeMap.reducer(map, type)
  File "/home/karicher/venv/lib64/python3.6/site-packages/graphql/type/typemap.py", line 87, in reducer
    if type_.name in map_:
AttributeError: type object 'function' has no attribute 'name'

I tried to replace [...] with individual filters and looks like the issue is only with the in filter. If I don't have in in the filter list, everything is working as expected.

class SampleFilter(FilterSet):
    class Meta:
        model = SampleModel
        fields = {
            'name': [...],
            'type': ['eq', 'ne'],
        }

... would work!

but,

class SampleFilter(FilterSet):
    class Meta:
        model = SampleModel
        fields = {
            'name': [...],
            'type': ['in'], # or [...]
        }

wouldn't work.

art1415926535 commented 4 years ago

What version of graphene and graphene-sqlalchemy you are using?

sreerajkksd commented 4 years ago

Sorry for the late reply.

These are the versions in use:

graphene (2.1.8)
graphene-sqlalchemy (2.3.0)
graphene-sqlalchemy-filter (1.11.1)
art1415926535 commented 4 years ago

I tested on your environment and found no errors. Looking at your stacktrace error occurs at the graphene level, but the message contains too little information... I don't know why you ran into this error. The only way I can help you is by checking a minimal example project that contains the same error.

sreerajkksd commented 3 years ago

Ok, I have more problems now. 'eq' filter for type field work in 1.11.0 but not in '1.12.1' type field is a enum variable which can have two values. Attaching the strack trace here.

20200928 10:18:13 ERROR Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/promise/promise.py", line 489, in _resolve_from_executor
    executor(resolve, reject)
  File "/usr/lib/python3.6/site-packages/promise/promise.py", line 756, in executor
    return resolve(f(*args, **kwargs))
  File "/usr/lib/python3.6/site-packages/graphql/execution/middleware.py", line 75, in make_it_promise
    return next(*args, **kwargs)
  File "/home/karicher/venv/server/lib64/python3.6/site-packages/graphene_sqlalchemy/fields.py", line 78, in connection_resolver
    return on_resolve(resolved)
  File "/home/karicher/venv/server/lib64/python3.6/site-packages/graphene_sqlalchemy/fields.py", line 51, in resolve_connection
    resolved = cls.get_query(model, info, **args)
  File "/home/karicher/venv/server/lib64/python3.6/site-packages/graphene_sqlalchemy_filter/connection_field.py", line 88, in get_query
    query = filter_set.filter(info, query, request_filters)
  File "/home/karicher/venv/server/lib64/python3.6/site-packages/graphene_sqlalchemy_filter/filters.py", line 752, in filter
    query, sqla_filters = cls._translate_many_filter(info, query, filters)
  File "/home/karicher/venv/server/lib64/python3.6/site-packages/graphene_sqlalchemy_filter/filters.py", line 878, in _translate_many_filter
    query, r = cls._translate_filter(info, query, k, v)
  File "/home/karicher/venv/server/lib64/python3.6/site-packages/graphene_sqlalchemy_filter/filters.py", line 839, in _translate_filter
    value = model_field_type.enum_class(value)
graphql.error.located_error.GraphQLLocatedError: 'NoneType' object is not callable

Can you test by converting type field to an enum and then try again ?

art1415926535 commented 3 years ago

Yeah. I got a similar error. As far as I understand, the error rise only if custom graphene objects used (if not use SQLAlchemyObjectType). I tried to fix it, but so far I'm at a dead end. So far, I do not have much free time for this bug... As soon as I fix it, I will immediately make a new release.

shark132 commented 3 years ago

I've got the same problem with enum field. The "in" filter works fine with other fileds, but rises the metioned error when I try to use it with enum field. graphene-sqlalchemy-filter = "==1.11.2"

Model:

status = db.Column(db.Enum(IssueStatus))

Schema:

class Meta:
    model = Issue
    fields = {
        'status': ['in'],
    }
sreerajkksd commented 3 years ago

@art1415926535 Can you take a look at this PR and see if we can fix this here ?

art1415926535 commented 3 years ago

I published a new release https://pypi.org/project/graphene-sqlalchemy-filter/1.12.2/ @sreerajkksd can you check it out?

sreerajkksd commented 3 years ago

@art1415926535 That seems to have fixed it and I started using the latest version in production :) I'll report if I come across any new issues. Thanks for the fix.

Good to close this issue from my side.