在 peewee 中转录 mySQL 查询时遇到问题

Having trouble transcribing mySQL query in peewee

我在 mySQL 中有一个查询,当输入 mySQL 终端时会产生所需的输出,但是,我在尝试在 Peewee ORM 中编写相同的查询时遇到了问题。

这里是 mySQL 查询:

select t.PATH, s.PATH from media_data as t 
left outer join media_data as s on 
s.SHOW = t.SHOW and s.EPISODE = t.EPISODE and s.SHOT = t.SHOT and s.FRAME = t.FRAME and t.LABEL_TYPE = 'target' 
where s.LABEL_TYPE = 'source' and s.SHOW = 'doc_d' and s.EPISODE = '102'        
union 
select t.PATH, s.PATH from media_data as t 
right outer join media_data as s on
s.SHOW = t.SHOW and s.EPISODE = t.EPISODE and s.SHOT = t.SHOT and s.FRAME = t.FRAME and t.LABEL_TYPE = 'target' 
where s.LABEL_TYPE = 'source' and s.SHOW = 'doc_d' and s.EPISODE = '102';
 

这是我对相应的 peewee 查询的尝试

s = media_data.alias()
t = media_data.alias()

predicate = (s.SHOW == t.SHOW and s.EPISODE == t.EPISODE and s.SHOT == t.SHOT 
             and s.FRAME == t.FRAME and t.LABEL_TYPE == 'target')

query = media_data.select(s.PATH, t.PATH).join(t, join_type=JOIN.FULL_OUTER, on=predicate).where(s.LABEL_TYPE == 'source' and s.SHOW == show and s.EPISODE == episode)

当我尝试 运行 python 时,它告诉我 'JOIN.FULL_OUTER' 有问题,即使它完全按照语法中的定义使用。

有几个问题。首先,您需要在谓词中使用 & 而不是 and 并使用括号正确绑定这些:

predicate = ((S.show == T.show) &
             (S.episode == T.episode) &
             (S.shot == T.shot) &
             (S.frame == T.frame) &
             (T.label_type == 'target'))

此外,如果您的数据库抱怨全外连接,也许它不支持这种类型的连接(因此是笨拙的 UNION 查询的原因)?

如果您已确认您的数据库 支持完全外部联接,那么以下操作应该有效:

T = MediaData.alias()

predicate = ((MediaData.show == T.show) &
             (MediaData.episode == T.episode) &
             (MediaData.shot == T.shot) &
             (MediaData.frame == T.frame) &
             (T.label_type == 'target'))

query = (MediaData
         .select(MediaData.path, T.path)
         .join(T, join_type=JOIN.FULL_OUTER, on=predicate)
         .where(
             (MediaData.label_type == 'source') &
             (MediaData.show == 'doc_d') &
             (MediaData.episode == '102')))

查询:

SELECT "t1"."path", "t2"."path"
FROM "mediadata" AS "t1"
FULL OUTER JOIN "mediadata" AS "t2" ON (
 ("t2"."show" = "t1"."show") AND 
 ("t2"."episode" = "t1"."episode") AND
 ("t2"."shot" = "t1"."shot") AND
 ("t2"."frame" = "t1"."frame") AND
 ("t2"."label_type" = 'target'))
WHERE (
 ("t1"."label_type" = 'source') AND 
 ("t1"."show" = 'doc_d')) AND
 ("t1"."episode" = '102'))