我現在有3個表大致描述爲以下的SQLAlchemy映射:查詢一個的鏈許多和多對一
class Task(BASE):
__tablename__ = 'tasks'
id = Column(Integer, primary_key=True)
service_id = Column(Integer, ForeignKey('services.id'))
service = relationship('Service', back_populates="tasks")
updates = relationship("TaskUpdate")
class TaskUpdate(BASE):
__tablename__ = 'task_updates'
id = Column(Integer, primary_key=True)
external_status = Column(String(32))
external_updated_at = Column(DateTime(timezone=True))
task_id = Column(Integer, ForeignKey('tasks.id'))
task = relationship('Task', back_populates="updates")
class Service(BASE):
__tablename__ = 'services'
id = Column(Integer, primary_key=True)
client_id = Column(Integer, ForeignKey('clients.id'))
client = relationship('Client', back_populates='services')
所以我有一對多的從任務關係TaskUpdates和許多從任務到服務。
我試圖創建一個查詢來獲取所有任務,其最新的TaskUpdate(通過時間戳)具有「新建」或「打開」的external_status。
這裏就是我的了:
sub = SESSION.query(
TaskUpdate.task_id,
TaskUpdate.external_status.label('last_status'),
func.max(TaskUpdate.external_updated_at).label('last_update')
).group_by(TaskUpdate.task_id
).subquery()
tasks = SESSION.query(Task
).join(Service
).filter(Service.client_id == client_id
).join((sub, sub.c.task_id == Task.id)
).filter(sub.c.last_status.in_(['New', 'Open']))
當我運行它,我得到這個錯誤:
ProgrammingError: (psycopg2.ProgrammingError) column "task_updates.external_status" must appear in the GROUP BY clause or be used in an aggregate function
我會很感激任何幫助,您可以給。這個很重要。
更新1(這是結束了工作的SQL(據我所知,我無法測試前端,直到我在SQLAlchemy中得到這個工作雖然:
SELECT t.* FROM (
SELECT DISTINCT ON (task_id) task_id, external_status
FROM task_updates
ORDER BY task_id, external_updated_at DESC NULLS LAST) tu
JOIN tasks t ON t.id = tu.task_id
JOIN services s ON s.id = t.service_id
WHERE s.client_id = '" + str(client_id) + "'
AND tu.external_status IN ('New', 'Open');
這是我嘗試轉換,仍然沒有工作:
sub = SESSION.query(TaskUpdate).distinct(TaskUpdate.task_id).order_by(TaskUpdate.task_id.desc().nullslast(), TaskUpdate.external_updated_at.desc().nullslast()).subquery()
tasks = SESSION.query(Task).join(Service).join(sub.c.task_id==Task.id).filter(TaskUpdate.external_status.in_(['New', 'Open']))
更新2:查詢下面我有工作,但是當我做.Count之間()返回總數TaskUpdates的,沒有任務,我懷疑查詢需要重做一種不同的方式,除非有人知道如何處理這個問題?
選擇T * FROM(SELECT DISTINCT ON(TASK_ID)TASK_ID,external_status FROM task_updates ORDER BY TASK_ID,external_updated_at DESC NULLS LAST)TU join任務T ON t.id = tu.task_id JOIN服務S ON秒。 .id = t.service _id WHERE s.client_id ='1'和tu.external_status IN('New','Open'); 這是最後的查詢工作,謝謝。現在我需要將其轉換爲SQLAlchemy。 –
如果您對此查詢進行計數,它將返回TaskUpdates的總數。這不是理想的行爲。有更清潔的嗎? –
@PhilSalesses:如果您對此查詢進行計數,它*不會*返回TaskUpdates的總數。你可以在task_updates中獲得至少有一個相關行的'tasks'中的行數。在某個地方肯定會有誤解。 –