【问题标题】:Representing sum types in sql with Persistent, and Esqueleto joins用 Persistent 和 Esqueleto 连接表示 sql 中的总和类型
【发布时间】: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


【解决方案1】:

按照 Waldheinz 的建议添加作为答案


我发现了问题所在;来自文档:

请注意,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)

问候,

迈克尔

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    • 2018-12-19
    相关资源
    最近更新 更多