Гибридное свойство SQLAlchemy для блока if else - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть модель Flask -SQLAlchemy с полями delivery_at и read_at DateType.

class Foo(db.Model):

    __tablename__ = 'foo'

    delivered_at = db.Column(db.DateTime)
    read_at = db.Column(db.DateTime, onupdate=datetime.datetime.now)

На основе полей данных я бы хотел вычислить status с использованием гибридного свойства. И то, что у меня сейчас выглядит, выглядит так:

    @hybrid_property
    def status(self):
        value = ('Opened', 'Received', 'Undelivered')

        if self.delivered_at and self.read_at:
            return value[0]
        elif self.delivered_at and not self.read_at:
            return value[1]
        else:
            return value[2]

@status.expression
    def status(cls):
        from sqlalchemy import text
        value = ('Opened', 'Received', 'Undelivered')
        return case(
            [(text('(foo.delivered_at is not null) and (foo.read_at is not null)'), value[0]),
             (text('(foo.delivered_at is not null) and (foo.read_at is null)'), value[1])], else_=value[2]
        )

Я могу сделать filter_by, но при группировании по мне выдается ошибка:

>>> res = Foo.query.filter_by(status='Opened').all()
>>> res
[<Foo 1>]

res = db.session.query(Foo.status, func.count(Foo.status)).group_by(Foo.status).all()

Traceback для group_by:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 3186, in all
    return list(self)
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 3342, in __iter__
    return self._execute_and_instances(context)
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 3367, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 988, in execute
    return meth(self, multiparams, params)
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/sql/elements.py", line 287, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1107, in _execute_clauseelement
    distilled_params,
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1253, in _execute_context
    e, statement, parameters, cursor, context
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1473, in _handle_dbapi_exception
    util.raise_from_cause(sqlalchemy_exception, exc_info)
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 398, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 152, in reraise
    raise value.with_traceback(tb)
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1249, in _execute_context
    cursor, statement, parameters, context
  File "/home/foo/.virtualenvs/bar/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 580, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) missing FROM-clause entry for table "foo"
LINE 1: SELECT CASE WHEN (foo.delivered_at is not null) ...

Любой совет?

...