esqueleto:外部连接无法编译

Posted

技术标签:

【中文标题】esqueleto:外部连接无法编译【英文标题】:esqueleto: outer join doesn't compile 【发布时间】:2018-01-16 13:49:15 【问题描述】:

这是我的模型的一个子集:

ServerWebsite
    desc Text
    url Text
    text Text
    username Text
    password Password
    serverDatabaseId ServerDatabaseId Maybe
    groupName Text Maybe
    serverId ServerId
    deriving Show Typeable
ServerDatabase
    desc Text
    name Text
    text Text
    username Text
    password Password
    groupName Text Maybe
    serverId ServerId
    deriving Show Typeable

我无法构建此查询:

filterServerWebsites :: SqlExpr (Value Text) -> SqlPersistM [Entity ServerWebsite]
filterServerWebsites query = select $ from $ \(w `LeftOuterJoin` db) -> do
    on (w ^. ServerWebsiteServerDatabaseId ==. db ?. ServerDatabaseId)
    where_ ((w ^. ServerWebsiteDesc `like` query)
        ||. (w ^. ServerWebsiteUrl `like` query)
        ||. (w ^. ServerWebsiteText `like` query)
        ||. (db ?. ServerDatabaseDesc `like` just query))
    return w

我不明白构建错误:

    • Couldn't match expected type ‘SqlQuery a1’
                  with actual type ‘(a0 -> b0) -> a0 -> a0 -> c0’
    • Probable cause: ‘on’ is applied to too few arguments
      In a stmt of a 'do' block:
        on (w ^. ServerWebsiteServerDatabaseId ==. db ?. ServerDatabaseId)

和:

    • Couldn't match expected type ‘b0 -> b0 -> c0’
                  with actual type ‘SqlExpr (Value Bool)’
    • Possible cause: ‘(==.)’ is applied to too many arguments
      In the first argument of ‘on’, namely
        ‘(w ^. ServerWebsiteServerDatabaseId ==. db ?. ServerDatabaseId)’

我不明白我哪里出错了?

编辑 我是从这段代码开始的,它确实有效:

filterServerWebsites :: SqlExpr (Value Text) -> SqlPersistM [Entity ServerWebsite]
filterServerWebsites query = select $ from $ \w -> do
    where_ ((w ^. ServerWebsiteDesc `like` query)
        ||. (w ^. ServerWebsiteUrl `like` query)
        ||. (w ^. ServerWebsiteText `like` query))
    return w

【问题讨论】:

ServerDatabaseId 真的是ServerDatabaseServerId 吗? 不,Server 表不相关。这里我们只有ServerWebsiteServerDatabase。尝试查询ServerWebsite 并通过serverDatabaseId ServerDatabaseId Maybe 获得ServerDatabase 的外部连接。所以ServerDatabaseIdServerDatabase 的PK。 嗯,好的。我不是 esqueleto 专家,但我认为 db ?. ServerDatabaseId 会访问 ServerDatabase 中不存在的字段 id。 (不过,我可能对此非常错误。) 据我了解dbMaybe 实体,因为它是外连接,因此正确的表可能没有记录。这就是我认为我们需要?. 而不是^. 的原因。 我不关心?.,而是关心ServerDatabaseId这个名字,因为上面的ServerDatabase没有id字段,只有一个serverId字段。 【参考方案1】:

没错。所以真的是我自己的愚蠢。我应该制作一个示例项目来重现该问题,然后我就会发现该问题。

问题是我在文件顶部...

import Database.Esqueleto hiding (on)
import Data.Function

...因为我在该文件中的其他位置使用 on 来自 Data.Function

我把它改成了……

import Database.Esqueleto
import qualified Data.Function as F

现在一切正常...

【讨论】:

以上是关于esqueleto:外部连接无法编译的主要内容,如果未能解决你的问题,请参考以下文章

内部链接和外部链接

简化 Persistent & Esqueleto 代码

无法让外部连接在 EF 中工作

PHPStorm 无法与 xdebug 建立外部连接

无法使用外部服务器上的 php 文件连接数据库(mysql)

HTTP 服务器:连接被外部主机关闭