持久的'upsert`不起作用

时间:2018-04-26 19:16:10

标签: haskell yesod

我显然对Persistent的upsert函数以及它如何与Postgres 9.5一起工作感到困惑。

我正在编写一个Yesod应用程序,它接受一个JSON值,解析它,然后在相应的数据库表上执行upsert。我已经验证了JSON被解析为有效值。见代码:

postITSClientsR :: Handler TypedContent
postITSClientsR = do
  i <- requireJsonBody :: Handler IntensiveTreatmentClient
  row <- runDB $ upsert i []
  selectRep . provideJson $ row

我还验证了此模型类型具有唯一性约束:

IntensiveTreatmentClient json
  clientId ClientId
  UniqueIntensiveTreatmentClientClientId clientId
  etc...

然而,我的新值并没有得到保存。我已经验证了几次,但Yesod日志可能是最有说服力的,因为它报告:

POST /api/itsClients
  Params: [("{\"clientId\":1,...","")]
  Request Body: {"clientId":1,...}
  Accept: */*
  Status: 200 OK 0.005041s

(有意删除字段以进行匿名处理)通常,日志会报告已运行的SQL查询,而且这不会报告任何内容。

发生了什么事? Yesod或Persistent只是默默地删除我的查询而没有错误。

1 个答案:

答案 0 :(得分:0)

我认为upsert评论是bug。 我打开了拉取请求added: PersistentTest: upsert fail, it expected equivalent repsert by ncaq · Pull Request #821 · yesodweb/persistent

当两个参数列表为空时,upsert不会更新。

如果您想要独特的代表。 此代码由我创建,可以与堆栈溢出cc许可证一起使用。

-- | if a record exist by unique, then 'replace', else 'insert'
repsertBy :: ( PersistEntityBackend record ~ BaseBackend backend
             , PersistStoreWrite backend
             , PersistEntity record
             , PersistUniqueRead backend
             , MonadIO m) =>
             record -> ReaderT backend m (Key record)
repsertBy record = do
    me <- getByValue record
    case me of
        Nothing             -> insert record
        Just (Entity key _) -> replace key record >> return key

但是,此代码在Yesod主流上被拒绝了。 因为,当存在多个唯一常量时,则无法定义。