【发布时间】:2014-10-10 18:40:06
【问题描述】:
我一直在尝试找出一种合理的方式来使用持久化在 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,永远不会同时有。
我想使用 Left 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 子句的顺序是颠倒的!你是 需要以相反的顺序写你的,因为这有帮助 可组合性(有关详细信息,请参阅 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)
谢谢,
迈克尔
【问题讨论】:
-
您能否将您的答案添加为下面的答案?如果它是问题的一部分,很容易错过您的解决方案,就像我现在几乎一样。
-
有人可以帮助解释为什么需要
just吗?elem表肯定有它自己的id。删除just时遇到错误。谢谢
标签: haskell yesod persistent esqueleto