【发布时间】:2022-01-21 14:52:47
【问题描述】:
我在 SQLAlchemy 中有以下模型:
class SomeEvent(db.Model):
id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
created_on = db.Column(db.DateTime())
type = db.Column(db.String(20))
event_target = db.Column(db.String(10))
group = db.Column(db.String(20))
有没有办法产生一个查询,该查询将返回一个结果,该结果由一个类型的所有记录 + 两个其他类型的记录(如果这两个记录具有相同的 event_target 否则只是一个类型的记录)的相同组排序通过created_on 日期?
我想出了什么:
Single_type_event = aliased(SomeEvent)
Paired_type_event_1 = aliased(SomeEvent)
Paired_type_event_2 = aliased(SomeEvent)
columns = [
Single_type_event.id.label('single_type_event_id'),
Single_type_event.type.label('single_type_event_type'),
Single_type_event.event_target.label('single_type_event_target'),
Paired_type_event_1.id.label('paired_type_event_1_id'),
Paired_type_event_1.type.label('paired_type_event_1_type'),
Paired_type_event_1.event_target.label('paired_type_event_1_target'),
Paired_type_event_2.id.label('paired_type_event_2_id'),
Paired_type_event_2.type.label('paired_type_event_2_type'),
Paired_type_event_2.event_target.label('paired_type_event_2_target'),
]
query = (db.session.query(*columns)
.outerjoin(SomeEvent, (
(SomeEvent.group == 'some_group') &
(SomeEvent.id == Single_type_event.id) |
(SomeEvent.id == Paired_type_event_1.id) |
(SomeEvent.id == Paired_type_event_2.id)
))
.outerjoin(Single_type_event, (
(SomeEvent.id == Single_type_event.id) &
(SomeEvent.event_target == Single_type_event.event_target) &
(SomeEvent.type == 'type_1')
))
.outerjoin(Paired_type_event_1, (
(SomeEvent.id == Paired_type_event_1.id) &
(SomeEvent.event_target == Paired_type_event_1.event_target) &
(SomeEvent.type == 'type_2')
))
.outerjoin(Paired_type_event_2, (
(SomeEvent.id == Paired_type_event_2.id) &
(SomeEvent.event_target == Paired_type_event_2.event_target) &
(SomeEvent.type == 'type_3')
))
.order_by(SomeEvent.created_on.asc())
)
但当然它不起作用,因为我缺乏对如何正确执行此操作的理解,如果可能的话 =(
我想达到的查询结果示例(._asdict()已申请):
- 如果具有给定
event_target的记录具有type == 'type_1':
{'single_type_event_id': 'some_id',
'single_type_event_type': 'type_1',
'single_type_event_target': 'target_1',
'paired_type_event_1_id': None,
'paired_type_event_1_type': None,
'paired_type_event_1_target': None,
'paired_type_event_2_id': None,
'paired_type_event_2_type': None,
'paired_type_event_2_target': None}
- 如果对于给定的
event_target,只有一条带有type == 'type_2'的记录(它之前也可以有一条type_1记录,但它应该像之前一样位于不同的行中):
{'single_type_event_id': None,
'single_type_event_type': None,
'single_type_event_target': None,
'paired_type_event_1_id': 'some_id',
'paired_type_event_1_type': 'type_2',
'paired_type_event_1_target': 'target_1',
'paired_type_event_2_id': None,
'paired_type_event_2_type': None,
'paired_type_event_2_target': None}
- 最后,如果对于给定的
event_target有两种事件类型的记录(每种类型不应该有不同的行 - 只有组合的这一行):
{'single_type_event_id': None,
'single_type_event_type': None,
'single_type_event_target': None,
'paired_type_event_1_id': 'some_id_1',
'paired_type_event_1_type': 'type_2',
'paired_type_event_1_target': 'target_1',
'paired_type_event_2_id': 'some_id_2',
'paired_type_event_2_type': 'type_3',
'paired_type_event_2_target': 'target_1'}
我希望所有这些结果具有相同的组并按 created_on 排序(对于最后一个示例,它应该按paired_type_event_1 日期排序)。
一个抽象的例子:
person_1(event_target) 住在 town_a(group) 中。他有他出生时间的记录(type == 'birth'),这是他的single_type_event(上面结果的第一个案例)。这个person_1也有开学记录(type == 'enrollment'),但是没有毕业记录。这是他的paired_type_event_1(结果的第二种情况)。如果此人有毕业记录 (type == 'graduation'),那么它将与注册记录显示在同一行中。假设这张表实际上是town_a的纸质记录簿,这些记录应该按以下顺序组织:出生(单行)->注册(另一行)(出生(单行)->注册+毕业(另一行)毕业的人)
我知道这看起来很混乱,对此我有一些坚定的怀疑,但如果可以在 SQLAlchemy 或使用原始 SQL 中实现,我将非常感谢您的指导!
【问题讨论】:
标签: python sql sqlalchemy