我一直在尝试找出一种明智的方法来使用持久性在 SQL 后端表示 Haskell 总和类型。
我的目标 Haskell 数据类型是
data Widget = FooWidget Int | BarWidget T.Text
data HElement = HElement
{ name :: T.Text
, widget :: Widget
}
我正在使用以下持久数据类型对它们进行建模:
Element
name T.Text
Foo
elementId ElementId
size Int
Bar
elementId ElementId
colour T.Text
每个元素只会有一个 Foo 或一个 Bar ,永远不会两者都有。
我想使用 aLeft Outer Join
来选择我的所有元素和相应的 Foo OR Bar。我的 Esqueleto 表达是:
select $
from $ \(elem `LeftOuterJoin` foo `LeftOuterJoin` bar) -> do
on (just (elem ^. ElementId) ==. foo ?. FooElementId)
on (just (elem ^. ElementId) ==. bar ?. BarElementId)
return (elem, foo, bar)
但是,当我执行代码时,出现错误:
user error (Postgresql.withStmt': bad result status FatalError (("PGRES_FATAL_ERROR","ERROR: missing FROM-clause entry for table
如果我删除第二个加入,给出:
select $
from $ \(elem `LeftOuterJoin` foo) -> do
on (just (elem ^. ElementId) ==. foo ?. FooElementId)
return (elem, foo)
代码运行没有错误。我确定这很明显,但我看不出我做错了什么。
编辑:我发现了问题所在;来自文档:
请注意,ON 子句的顺序是颠倒的!您需要以相反的顺序编写您的 ons,因为这有助于可组合性(有关更多详细信息,请参阅 on 的文档)。
以下代码有效(on
表达式的顺序颠倒了):
select $
from $ \(elem `LeftOuterJoin` foo `LeftOuterJoin` bar) -> do
on (just (elem ^. ElementId) ==. bar ?. BarElementId)
on (just (elem ^. ElementId) ==. foo ?. FooElementId)
return (elem,foo,bar)
谢谢,
迈克尔