объединение sqlalchemy one to many в приложении flask для получения максимальной даты

#python #flask #sqlalchemy #flask-sqlalchemy

#python #flask #sqlalchemy #flask-sqlalchemy

Вопрос:

Мои данные
идентификатор строки, задание (не уникальное), статус, дата.

Запрос нужен
Возвращает результаты, уникальные по заданию,
максимальная дата статуса == 1 и
максимальная дата статуса == 0
в одной и той же возвращаемой строке.

почему это не работает (и это лучший подход?)?:

 from sqlalchemy import func
from sqlalchemy.orm import aliased

j=aliased(models.Jobs)

y=db.session.query(j.job,j.status,
  func.max(j.start).
  label("start")).
  filter(j.status ==0).
  group_by(j.job)   

x=db.session.query(models.Jobs.job,
  models.Jobs.status,
  func.max(models.Jobs.start).
  label("start")).
  filter(models.Jobs.status ==1).
  group_by(models.Jobs.job)

  nj=x.join(y,x[0]==y[0])#i tried x.job, but it claimed it didn't have a job
  

трассировка s дает мне

 >>> nj=x.join(y,x[0]==y[0])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "K:MeinzerProductionProjectManagementflasklibsite-packagessqlalche
myormquery.py", line 1638, in join
    from_joinpoint=from_joinpoint)
  File "<string>", line 1, in <lambda>
  File "K:MeinzerProductionProjectManagementflasklibsite-packagessqlalche
myormquery.py", line 50, in generate
    fn(self, *args[1:], **kw)
  File "K:MeinzerProductionProjectManagementflasklibsite-packagessqlalche
myormquery.py", line 1767, in _join
    outerjoin, create_aliases, prop)
  File "K:MeinzerProductionProjectManagementflasklibsite-packagessqlalche
myormquery.py", line 1807, in _join_left_to_right
    onclause, outerjoin)
  File "K:MeinzerProductionProjectManagementflasklibsite-packagessqlalche
myormquery.py", line 1952, in _join_to_left
    "Tried joining to %s, but got: %s" % (right, ae))
sqlalchemy.exc.InvalidRequestError: Could not find a FROM clause to join from.
Tried joining to SELECT jobs_1.job AS job, jobs_1.status AS jobs_1_status, max(j
obs_1.start) AS start
FROM jobs AS jobs_1
WHERE jobs_1.status = :status_1 GROUP BY jobs_1.job, but got: Can't find any for
eign key relationships between 'jobs' and '_FromGrouping object'. Perhaps you me
ant to convert the right side to a subquery using alias()?
>>>
  

Вот моя модель (должен ли я начинать с синтаксиса?)

 class Syntax(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    filename = db.Column(db.String(150), unique=True,)
    jobs = db.relationship('Jobs',lazy='dynamic', backref='jobhistory')
    position = db.Column(db.Integer)
    def __repr__(self):
        return '<filename %r>' % (self.filename)

class Jobs(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    job = db.Column(db.String(150),db.ForeignKey('syntax.filename'))
    start = db.Column(db.DateTime)
    stop = db.Column(db.DateTime)
    status = db.Column(db.Integer())  
    when = db.Column(db.String(150))  
    cat= db.Column(db.String(150))  
    message  = db.Column(db.String(150))  
    errorvar = db.Column(db.String(150))   
    errormsgvar = db.Column(db.String(150))  
    # syntaxhistory_id = db.Column(db.String, db.ForeignKey('syntax.filename')) 
    def __repr__(self):
        return '<Job %r>' % (self.job)
  

Комментарии:

1. Показать полную обратную трассировку, есть номер строки, в котором есть проблема. Покажите эту строку и окрестности.

2. Может быть, вам нужно jobs вместо job в каком-то месте.

Ответ №1:

Приведенный ниже запрос вернет данные, которые вы ищете, в виде списка кортежей (Syntax, max_start0, max_start1) :

 q = (db.session.query(Syntax,
        func.max(case([(Jobs.status == 0, Jobs.start)])).label("max_start0"),
        func.max(case([(Jobs.status == 1, Jobs.start)])).label("max_start1"),
        )
    .outerjoin(Jobs)
    .group_by(Syntax)
    )
  

Если вам нужны только filename (а не все Syntax экземпляры), просто замените Syntax на Syntax.filename в обоих query(...) и group_by(...) .

Комментарии:

1. потрясающе, спасибо! Я скоро помогу вам с вашими запросами!