Pegase745 / sqlalchemy-datatables

SQLAlchemy integration of jQuery DataTables >= 1.10.x (Pyramid and Flask examples)
MIT License
159 stars 67 forks source link

Clarification on hybrid property use in ColumnDT #103

Closed baryonyx5 closed 6 years ago

baryonyx5 commented 6 years ago

First, I thank you for this project as it has worked quite well for me.

I see in the ColumnDT doc string that hybrid properties are valid for the sql expression. I also saw a previous issue (https://github.com/Pegase745/sqlalchemy-datatables/issues/92) that elaborated a bit. I may be missing something but this does not seem to work for me.

I've used the simple model you defined as an example in the linked-to issue

from datatables import ColumnDT, DataTables. 
query = s.query(MyModel)
params = {'draw': 1, 'length': '-1', 'start': 0}. 
columns = [ColumnDT(MyModel.id), ColumnDT(MyModel.full_name)]. 
table = DataTables(params, query, columns). 

This raise the following:

InvalidRequestError                       Traceback (most recent call last)
<ipython-input-8-d150299371fc> in <module>()
      4 columns = [ColumnDT(MyModel.id), ColumnDT(MyModel.full_name)]
      5 try:
----> 6     table = DataTables(params, query, columns)
      7 except Exception as e:
      8     print(e)

~/.venv/lib/python3.6/site-packages/datatables/__init__.py in __init__(self, request, query, columns, allow_regex_searches)
    235         self.error = None
    236         try:
--> 237             self.run()
    238         except Exception as exc:
    239             raise

~/.venv/lib/python3.6/site-packages/datatables/__init__.py in run(self)
    314         # add columns to query
    315         query = query.add_columns(
--> 316             *[c.sqla_expr for c in self.columns])
    317         # fetch the result of the queries
    318         column_names = [col.mData if col.mData else str(i)

<string> in add_columns(self, *column)

~/.venv/lib/python3.6/site-packages/sqlalchemy/orm/base.py in generate(fn, *args, **kw)
    199         for assertion in assertions:
    200             assertion(self, fn.__name__)
--> 201         fn(self, *args[1:], **kw)
    202         return self
    203     return generate

~/.venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py in add_columns(self, *column)
   1245         l = len(self._entities)
   1246         for c in column:
-> 1247             _ColumnEntity(self, c)
   1248         # _ColumnEntity may add many entities if the
   1249         # given arg is a FROM clause

~/.venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py in __init__(self, query, column, namespace)
   3906             raise sa_exc.InvalidRequestError(
   3907                 "SQL expression, column, or mapped entity "
-> 3908                 "expected - got '%r'" % (column, )
   3909             )
   3910         elif not check_column:

InvalidRequestError: SQL expression, column, or mapped entity expected - got ''MyModel.first_name-MyModel.last_name''

I'm not sure how this could work unless I'm missing a step or the model requires a hybrid expression

Any clarification would be appreciated.

Thank you

ChuckWoodraska commented 6 years ago

What's your hybrid expression look like?

baryonyx5 commented 6 years ago

I used the same code from https://github.com/Pegase745/sqlalchemy-datatables/issues/92

class MyModel(Base):
    __tablename__ = 'my_model'

    id = Column(Integer, primary_key=True)
    first_name = Column(String, nullable=False)
    last_name = Column(String, nullable=False)
    value = Column(Integer, nullable=False)

    @hybrid_property
    def full_name(self):
        return '%s-%s' % (self.first_name, self.last_name)
tdamsma commented 6 years ago

I think you should be using column properties. If you really have to use hybrid properties, it has to be valid sql, or you have to separately define the expression, see the sqlalchemy docs

baryonyx5 commented 6 years ago

Using a hybrid expression does work and I'm guessing that's the way to go. The ColumnDT docstring and that previous issue refer to hybrid property so I wanted to clarify.

Thanks

panpanagos commented 5 years ago

I have the same problem and i can't solve it . Can you present the example with the hybrid expression you used ?