pyeve / eve-sqlalchemy

SQLAlchemy data layer for Eve-powered RESTful APIs
http://eve-sqlalchemy.readthedocs.io
Other
234 stars 70 forks source link

projections not working #56

Closed mandarvaze closed 7 years ago

mandarvaze commented 9 years ago

Problem

As soon as I try to put datasource['projections'] for a resource, I get a huge stack trace that doesn't give a clue as to why this is failing.

This error is seen for GET as well as for POST

Here is the snippet of the code:

DOMAIN['people'].update({
    'datasource': {
        'projection': {'lastname': 0}
    }
})

people is same as defined in the documentation. Nothing fancy. I really want to hide (encrypted) password field from the GET response to user resource. lastname is just any column used for testing

What works

When I comment the above code, there is no stack trace, but then lastname field is returned in the GET response.

projections work when used as query argument. e.g Using httpie module http command as follows works well. i.e. lastname is supressed from the GET response

http http://127.0.0.1:5000/people\?projection\=\{\"lastname\":0\}

Setup

SQLite DB Python 3.4 on OSX

Module Versions: Eve==0.5.3 Eve-SQLAlchemy==0.3.4

Others modules that might be interacting with eve-sqlalchemy Flask==0.10.1 Flask-SQLAlchemy==2.0 SQLAlchemy==1.0.6 SQLAlchemy-Utils==0.30.12

goneri commented 9 years ago

I don't have the problem with the current git version. Can you post the stack trace, maybe a subset with the error at least.

mandarvaze commented 9 years ago

I've upgraded (eve-sqlalchemy) to 0.4.0a1, still I have the same problem.

Traceback (most recent call last):
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve/endpoints.py", line 52, in collections_endpoint
    response = get(resource, lookup)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve/methods/common.py", line 239, in rate_limited
    return f(*args, **kwargs)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve/auth.py", line 68, in decorated
    return f(*args, **kwargs)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve/methods/common.py", line 820, in decorated
    r = f(resource, **combined_args)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve/methods/get.py", line 99, in get
    cursor = app.data.find(resource, req, lookup)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve_sqlalchemy/__init__.py", line 132, in find
    args['sort'], client_embedded)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve_sqlalchemy/__init__.py", line 298, in _datasource_ex
    client_sort)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve/io/base.py", line 373, in _datasource_ex
    datasource, filter_, projection_, sort_ = self._datasource(resource)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve_sqlalchemy/__init__.py", line 286, in _datasource
    model = self._model(resource)
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve_sqlalchemy/__init__.py", line 264, in _model
    return self.lookup_model(self._source(resource))
  File "/path/to/eve-sqla-pg/py3env/lib/python3.4/site-packages/eve_sqlalchemy/__init__.py", line 75, in lookup_model
    return cls.driver.Model._decl_class_registry[model_name]
  File "/usr/local/Cellar/python3/3.4.3/Frameworks/Python.framework/Versions/3.4/lib/python3.4/weakref.py", line 125, in __getitem__
    o = self.data[key]()
KeyError: 'users'
mandarvaze commented 9 years ago

@goneri Can you provide a working sample where projections are used the way I tried to use it ? The test cases have the projections used as part of the URL, which are already working for me.

pieterlouw commented 8 years ago

@mandarvaze I received this problem as well. What I did wrong was to re-declare Base in my run.py instead of importing it from my tables.py.

So basically I had Base = declarative_base()

in run.py which I replaced with

from tables import Base

dkellner commented 7 years ago

The problem here is most likely caused by using update: It will replace the value of the 'datasource' key and not recursively apply "update" if the value is a dictionary.

A working example can be created by adding

SETTINGS['DOMAIN']['people']['datasource']['projection']['lastname'] = 0

to trivial.py.

But be aware that fields hidden this way can still be read by applying the projection as query parameter:

curl -g 'http://localhost:5000/people?projection={"lastname":1}'
mandarvaze commented 7 years ago

@dkellner As I originally mentioned, I want to "hide" the (encrypted) password. How can I make sure that even with query param, password is NOT returned ?