flask-restless
flask-restless copied to clipboard
association proxy error: Class object expected, got 'None'.
NOTE: this isn't a priority for me right now, so I may not be able to answer questions or do further debugging.
Sidenote: according to https://github.com/jfinkels/flask-restless/issues/321#issuecomment-198327761 support for association proxies is necessary for many-to-many support, but why? I'm able to get many-to-many related data as long as I pass the proper includes
parameter.
I'm pretty new to this stuff so it's possible I'm misconfiguring something.
I have a reproduction at https://gitlab.com/jcrben-repro/flask-restless-assoc-bug - flask-restless is committed in that repo but the version is roughly demonstrated by the commented out requirements.txt line: -e [email protected]:jfinkels/flask-restless.git@8e32477deba1404a11f08bd9311a6122c6b8a31e#egg=Flask_Restless
Stack trace:
--------------------------------------------------------------------------------
ERROR in base [/Users/bencreasy/code/starter-python/flask-restless/flask_restless/views/base.py:664]:
Class object expected, got 'None'.
--------------------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/bencreasy/code/starter-python/flask-restless/flask_restless/views/base.py", line 450, in wrapped
return func(*args, **kw)
File "/Users/bencreasy/code/starter-python/flask-restless/flask_restless/views/resources.py", line 403, in get
return self._get_resource(resource_id)
File "/Users/bencreasy/code/starter-python/flask-restless/flask_restless/views/resources.py", line 336, in _get_resource
return self._get_resource_helper(resource)
File "/Users/bencreasy/code/starter-python/flask-restless/flask_restless/views/base.py", line 1583, in _get_resource_helper
included = self.get_all_inclusions(resource)
File "/Users/bencreasy/code/starter-python/flask-restless/flask_restless/views/base.py", line 1425, in get_all_inclusions
result = simple_serialize_many(to_include, only=only)
File "/Users/bencreasy/code/starter-python/flask-restless/flask_restless/serialization/serializers.py", line 534, in serialize_many
serialized = serializer.serialize(instance, only=_only)
File "/Users/bencreasy/code/starter-python/flask-restless/flask_restless/serialization/serializers.py", line 493, in serialize
resource = self._dump(instance, only=only)
File "/Users/bencreasy/code/starter-python/flask-restless/flask_restless/serialization/serializers.py", line 315, in _dump
assoc_scalars = list(assoc_proxy_scalar_collections(model))
File "/Users/bencreasy/code/starter-python/flask-restless/flask_restless/helpers.py", line 87, in assoc_proxy_scalar_collections
and not isinstance(v.remote_attr.property, RelationshipProperty) \
File "/Users/bencreasy/dotfiles/local/pyenv/versions/3.6.1/envs/starter-python/lib/python3.6/site-packages/sqlalchemy/ext/associationproxy.py", line 175, in remote_attr
return getattr(self.target_class, self.value_attr)
File "/Users/bencreasy/dotfiles/local/pyenv/versions/3.6.1/envs/starter-python/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 764, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/Users/bencreasy/dotfiles/local/pyenv/versions/3.6.1/envs/starter-python/lib/python3.6/site-packages/sqlalchemy/ext/associationproxy.py", line 225, in target_class
return self._get_property().mapper.class_
File "/Users/bencreasy/dotfiles/local/pyenv/versions/3.6.1/envs/starter-python/lib/python3.6/site-packages/sqlalchemy/ext/associationproxy.py", line 214, in _get_property
return (orm.class_mapper(self.owning_class).
File "/Users/bencreasy/dotfiles/local/pyenv/versions/3.6.1/envs/starter-python/lib/python3.6/site-packages/sqlalchemy/orm/base.py", line 425, in class_mapper
"Class object expected, got '%r'." % (class_, ))
sqlalchemy.exc.ArgumentError: Class object expected, got 'None'.
127.0.0.1 - - [19/Nov/2017 07:34:07] "GET /api/users/1 HTTP/1.1" 400 -
Basically self.owning_class ends up as None which seems to be due to shadowing caused by the memoized_property decorator at https://github.com/zzzeek/sqlalchemy/blob/bb21dea84cd6bc70ab12acb61d1f4511a013f90d/lib/sqlalchemy/ext/associationproxy.py#L90
I also mentioned this in the #sqlalchemy IRC channel as it seems possibly a core bug, but held off since I haven't reproduced it without the dependencies.