给出一个模型:
class Model(Base):
__tablename__ = 'dummy'
insert_date = Column(Date())
pk = Column(Integer())
...
我需要复制以下sql查询:
select a.*
from (select * from dummy where insert_date = TODAY) a
left join (select distinct pk from dummy where insert_date < TODAY) b
using (pk)
where b.(whatever) IS/IS NOT Null
但是我需要sqlalchemy来返回对象,而不是列的元组(这是我目前正在使用的)。
用语言来说,我基本上实现了,
&#34;获取第一次插入的所有虚拟记录 昨天&#34;
和
&#34;获取昨天更新的所有虚拟记录&#34;
取决于语句的IS或IS NOT NULL部分。每 pk将有多个条目。您不能依赖更新日期过滤。 应该注意,pk将是下一个表中的主键,但它不是当前表中的主键。
例如,
in dummy:
Inserted Tuesday, pk=1, ....
Inserted Wednesday, pk=1, ....
Inserted Wednesday, pk=2, ....
pk = 1将返回&#39; IS NOT NULL&#39; pk = 2将返回&#39; IS NULL&#39;
我已经得到以下内容来返回记录:
a = session.query(model).filter(model.date_retrieval==task_date).subquery()
b = session.query(model).filter(model.date_retrieval<task_date).subquery()
c = session.query(a, b).outerjoin(b, and_(a.c.pk==b.c.pk, a.c.seq==b.c.seq))
返回:
c.all()[0] :
(datetime.date(2015, 7, 1),
0,
1511,
u'431889',
u'7',
u'N',
u'0',
u'0',
u'0',
u'',
u'',
u'',
u'2',
u'5',
u'554428',
u'H',
u'9',
u'901',
datetime.date(2015, 6, 30),
0,
3487,
u'431889',
u'7',
u'N',
u'0',
u'0',
u'0',
u'',
u'',
u'',
u'2',
u'5',
u'554428',
u'H',
u'9',
u'901')
然后是
的内容[indv for indv in c if indv[-1] ] and [indv for indv in c if indv[-1] == None ]
从IS NULL情况中划分IS NOT NULL
编辑1:
主键是由insert_date,insert_seq组成的复合键 (&#39; 2015-07-08&#39;,0),(&#39; 2015-07-08&#39;,1),(&#39; 2015-07-08&#39;,2) ...
答案 0 :(得分:1)
我认为您可以使用以下代码执行您想要的操作:
a = aliased(Model, name="a")
b = aliased(Model, name="b")
q = (
session
.query(a)
.outerjoin(b, and_(a.pk == b.pk, b.insert_date < task_date))
.filter(a.insert_date == task_date)
.filter(b.pk == None)
# or: .filter(b.pk != None)
)
它不会产生相同的sql
,但我认为它在语义上是相同的。
另一种(在我看来,更干净)的方式是使用exists
或~exists
:
q = (
session
.query(a)
.filter(a.insert_date == task_date)
.filter(
exists(
# or: ~exists(
select([b.pk])
.where(a.pk == b.pk)
.where(b.insert_date < task_date)
)
)
)