我试图用PostgreSQL在Persistent中做一些看起来很简单的事情:给定一个Attendance
记录列表,用相同的惟一键覆盖任何现有的行,如果它们不存在,则插入它们。以下是这些类型:
share [mkPersist sqlSettings, mkDeleteCascade sqlSettings, mkMigrate "migrateAllEvents"] [persistLowerCase|
Event json sql=events
description Text
date UTCTime
UniqueEvent date
Attendance json
attending Bool
eventId EventId
user UserId
UniqueAttendance eventId user
|]
我没有钥匙,所以我不能使用repsert
,但我认为upsert
是我需要的。documentation for upsert
对我来说看起来有点模糊:如果记录存在,而我将更新保留为空,我知道它将保留实体的原样。但这并不等同于repsert
声称的行为,不是吗?它也没有说明当不存在唯一性约束时会发生什么。
我尝试的是
runDb (mapM_ ups atts)
where
-- ups rec = upsert rec [AttendanceAttending =. True] also doesn't work
ups rec = upsert rec [AttendanceAttending =. (attendanceAttending rec)]
但这导致了一个我不太理解的错误:
• Illegal equational constraint BaseBackend backend ~ SqlBackend
(Use GADTs or TypeFamilies to permit this)
• When checking the inferred type
ups :: forall (m :: * -> *) backend.
(BaseBackend backend ~ SqlBackend, PersistUniqueWrite backend,
MonadIO m) =>
Attendance -> ReaderT backend m (Entity Attendance)
你知道是什么导致了这个错误吗?upsertBy
也是一样的。我在同一个文件中导入了Esqueleto,但是是hiding ((=.))
,所以它应该是纯持久化的。
发布于 2018-01-20 18:45:35
令人尴尬的是,它真的和添加{-# LANGUAGE TypeFamilies #-}
一样简单。我没有尝试过,因为我误读了错误消息,而我的其他模块都不需要那个扩展。谢谢,Fyodor!
https://stackoverflow.com/questions/48350898
复制相似问题