mrevutskyi / flask-restless-ng

A Flask extension for creating simple ReSTful JSON APIs from SQLAlchemy models.
https://flask-restless-ng.readthedocs.io
Other
64 stars 11 forks source link

`selectinload_included_relationships` help uses hardcoded 'id' instead of passed `primary_key` #26

Closed tanj closed 3 years ago

tanj commented 3 years ago

When fetching relationships in a database that doesn't use id as the name of the table primary key the function selectinload_included_relationships causes an exception.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask\app.py", line 2088, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask\app.py", line 2073, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask_cors\extension.py", line 165, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask\app.py", line 2070, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask\app.py", line 1515, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask_cors\extension.py", line 165, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask\app.py", line 1513, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask\app.py", line 1499, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask_restless\views\base.py", line 433, in new_func
    data, status_code, headers = func(*args, **kw)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask_restless\views\base.py", line 407, in new_func
    return func(*args, **kw)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask_restless\views\base.py", line 372, in new_func
    return func(*args, **kw)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask_restless\views\base.py", line 247, in new_func
    return func(*args, **kw)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask\views.py", line 83, in view
    return self.dispatch_request(*args, **kwargs)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask_restless\views\base.py", line 1088, in dispatch_request
    return self.get_data(*args, include=include, **kwargs)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\flask_restless\views\base.py", line 1222, in get_data
    print(item)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\orm\query.py", line 2874, in __str__
    return str(statement.compile(bind))
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\sql\elements.py", line 489, in compile
    return self._compiler(dialect, **kw)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\sql\elements.py", line 553, in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\sql\compiler.py", line 766, in __init__
    Compiled.__init__(self, dialect, statement, **kwargs)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\sql\compiler.py", line 455, in __init__
    self.string = self.process(self.statement, **compile_kwargs)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\sql\compiler.py", line 490, in process
    return obj._compiler_dispatch(self, **kwargs)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\sql\visitors.py", line 82, in _compiler_dispatch
    return meth(self, **kw)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\sql\compiler.py", line 3011, in visit_select
    compile_state = select_stmt._compile_state_factory(
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\sql\base.py", line 500, in create_for_statement
    return klass.create_for_statement(statement, compiler, **kw)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\orm\context.py", line 628, in create_for_statement
    opt.process_compile_state(self)
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\orm\strategy_options.py", line 194, in process_compile_state
    self._process(
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\orm\strategy_options.py", line 730, in _process
    val._bind_loader(
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\orm\strategy_options.py", line 911, in _bind_loader
    if not loader._generate_path(
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\orm\strategy_options.py", line 273, in _generate_path
    util.raise_(
  File "C:\Users\<USERNAME>\AppData\Local\pypoetry\Cache\virtualenvs\pce-testsheets-g8TS-oaq-py3.8\Lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
    raise exception
sqlalchemy.exc.ArgumentError: Can't find property named "id" on mapped class TCustomer->tCustomer in this Query.

What I would expect to happen

I would expect the primary_key used in defining of the relationship's endpoint to be used.

mrevutskyi commented 3 years ago

Ugh, don't know how I overlooked that. Thank you for reporting. Disabled that part as for now there is no tracking of relationships schemas.

Fixed in 2.0.3

mrevutskyi commented 3 years ago

Found a way to use primary_key, added back in 2.1.1