Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

association proxy error: Class object expected, got 'None'. #669

Open
jcrben opened this issue Nov 19, 2017 · 0 comments
Open

association proxy error: Class object expected, got 'None'. #669

jcrben opened this issue Nov 19, 2017 · 0 comments

Comments

@jcrben
Copy link

jcrben commented Nov 19, 2017

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 #321 (comment) 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 git+git@github.com: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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant