持久upsert不编译

时间:2018-01-19 23:17:53

标签: haskell haskell-persistent

我试图在Persistent with PostgreSQL中做一些看似简单的事情:给定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 ((=.)),所以它应该是纯粹的持久性。

1 个答案:

答案 0 :(得分:1)

令人尴尬的是,它真的像添加{-# LANGUAGE TypeFamilies #-}一样简单。我没有尝试过,因为我误读了错误消息,我的其他模块都没有需要该扩展。谢谢,费奥多尔!