Как определить Flask -SQLAlchemy (MySQL) гибридную собственность или агрегированные атрибуты для сравнения DateTime - PullRequest
0 голосов
/ 21 марта 2020

Например, есть объект Task (родительский) в базе данных и объекты Study (дочерние). Объекты исследования имеют свойства начала и окончания sh времени. Как определить два гибридных свойства для объекта Task. Один для самого раннего времени запуска среди его «задач», а другой - для самого последнего конечного sh времени среди его «задач.

В документации говорится, что для определения этих самых ранних / последних можно использовать агрегированные атрибуты или гибридные свойства. атрибуты, но я не смог, как сравнить объекты sa.DateTime и как написать эти sql запросы для них.

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.sql import func as safunc

sa=SQLAlchemy()


class Task(sa.Model):
    __tablename__ = "tasks"
    id = sa.Column(sa.Integer, primary_key=True)
    studies = sa.relationship("Study", backref="task", cascade="all, delete, delete-orphan")

    @hybrid_propery
    def start(self):
        # ???

    @start.expression
    def start(cls):
        # ???

    @hybrid_propery
    def last_progress(self):
        # ???

    @last_progress.expression
    def last_progress(cls):
        # ???


class Study(sa.Model):
    __tablename__ = "studies"
    id = sa.Column(sa.Integer, primary_key=True)
    task_id = sa.Column(sa.Integer, sa.ForeignKey("tasks.id"))
    start = sa.Column(sa.DateTime, server_default=safunc.now())
    finish = sa.Column(sa.DateTime, nullable=True)

1 Ответ

0 голосов
/ 21 марта 2020

Я обработал его, используя python метод min / max в гибридном свойстве и функции min / max в sqlalchemy. sql .fun c в выражении свойства, код работает нормально.

task = Task.query.filter_by(id=id).first()

task.start запрос возвращает самую раннюю начальную запись исследования, а task.last_progress возвращает самое последнее время окончания исследования для этой задачи, как я искал.

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.sql import func as safunc

sa=SQLAlchemy()


class Task(sa.Model):
    __tablename__ = "tasks"
    id = sa.Column(sa.Integer, primary_key=True)
    studies = sa.relationship("Study", backref="task", cascade="all, delete, delete-orphan")

    @hybrid_propery
    def start(self):
        if any(i.start for i in self.studies):
            return min(filter(lambda x: x, [i.start for i in self.studies]))
        else:
            return None

    @start.expression
    def start(cls):
        return select([safunc.min(Study.start)]).\
                where(Study.task_id==cls.id).\
                label("start")

    @hybrid_propery
    def last_progress(self):
        if any(i.finish for i in self.studies):
            return max(filter(lambda x: x, [i.finish for i in self.studies]))
        else:
            return None

    @last_progress.expression
    def last_progress(cls):
        return select([safunc.max(Study.finish)]).\
                where(Study.task_id==cls.id).\
                label("last_progress")


class Study(sa.Model):
    __tablename__ = "studies"
    id = sa.Column(sa.Integer, primary_key=True)
    task_id = sa.Column(sa.Integer, sa.ForeignKey("tasks.id"))
    start = sa.Column(sa.DateTime, server_default=safunc.now())
    finish = sa.Column(sa.DateTime, nullable=True)
...