无法使用Esqueleto编写双左连接

Sea*_*ean 7 haskell esqueleto

我有一个教师,学校和地区的数据库模式.该TEACHERS表具有可以为空的SCHOOL_ID列(教师可能属于或可能不属于学校),并且该SCHOOLS表具有可为空的DISTRICT_ID列(学校可能属于或可能不属于某个区).

使用Esqueleto,我想要一个教师名单,每个教师都有一所学校(如果他们属于一所学校)和一个学区(如果他们属于属于某个学区的学校).花了一点时间才找出适合老师的正确表达 - >学校左连接,但我最终做对了:

select $
from $ \(teacher `LeftOuterJoin` school) -> do
  on (teacher ^. TeacherSchoolId  ==. school ?. SchoolId)
  return (teacher, school)
Run Code Online (Sandbox Code Playgroud)

我尝试DISTRICTS使用类似的表达式添加另一个左连接:

select $
from $ \(teacher `LeftOuterJoin` school `LeftOuterJoin` district) -> do
  on (school  ^. SchoolDistrictId ==. district ?. DistrictId)
  on (teacher ^. TeacherSchoolId  ==. school   ?. SchoolId)
  return (teacher, school, district)
Run Code Online (Sandbox Code Playgroud)

但是我收到一个错误:

Couldn't match type ‘Entity School’ with ‘Maybe (Entity School)’
Expected type: SqlExpr (Maybe (Entity School))
  Actual type: SqlExpr (Entity School)
In the first argument of ‘(?.)’, namely ‘school’
In the second argument of ‘(==.)’, namely ‘school ?. SchoolId’
Run Code Online (Sandbox Code Playgroud)

可以使用Esqueleto表示这种双连接吗?如果是这样,怎么样?

bit*_*app 3

Try changing

 on (teacher ^. TeacherSchoolId  ==. school   ?. SchoolId)
Run Code Online (Sandbox Code Playgroud)

To

 on (teacher ^. TeacherSchoolId  ==. just (school   ?. SchoolId))
Run Code Online (Sandbox Code Playgroud)

If that doesn't work, slap 'just' on other components of the query expression until it works.

Reference: used Esqueleto recently on a commercial project

Update, 2016/10/26:

I recently encountered this problem. I think it's a Persistent serialization problem interacting with Esqueleto's willingness to pretend the join doesn't produce nullable results.

I recently changed a fragment of a query from:

  person  `LeftOuterJoin`
  personExtra
 ) -> do
  on ((personExtra ^. PersonExtraPerson) ==. (person ^. PersonId))
Run Code Online (Sandbox Code Playgroud)

to:

  person  `LeftOuterJoin`
  personExtra
 ) -> do
  on ((personExtra ?. PersonExtraPerson) ==. just (person ^. PersonId))
Run Code Online (Sandbox Code Playgroud)

I also changed the return type of my query from Entity PersonExtra to Maybe (Entity PersonExtra).

Now Persistent expects the possibility of a PersistNull and the query works fine for me.