我显然对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只是默默地删除我的查询而没有错误。
答案 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主流上被拒绝了。 因为,当存在多个唯一常量时,则无法定义。