Type-safe, multi-backend data serialization.

Version on this page:2.9.1@rev:1
LTS Haskell 21.13:
Stackage Nightly 2023-09-30:
Latest on Hackage:

See all snapshots persistent appears in

MIT licensed by Michael Snoyman
This version can be pinned in stack with:persistent-2.9.1@sha256:205a146f5a90569da1b5c9e078a9e0aaf0baddef83e67d2be8ae3a751b4bcfc6,4921


Type-safe, data serialization. You must use a specific backend in order to make this useful. For more information, see the chapter in the Yesod book.


Changelog for persistent


  • Fix #847: SQL error with putMany on Sqlite when Entity has no unique index.


  • Added support for SQL isolation levels to via SqlBackend. [#812]
  • Move Database.Persist.Sql.Raw.QQ to a separate persistent-qq package #827
  • Fix 832: repsertMany now matches mapM_ (uncurry repsert) and is atomic for supported sql back-ends.


  • Added support for sql= to the unique constraints quasi-quoter so that users can specify the database names of the constraints.


  • DRY-ed up and exposed several util functions in Database.Persist.Sql.Util.
    • Upstream-ed updatePersistValue, mkUpdateText, and commaSeparated from Database.Persist.MySQL.
    • De-duplicated updatePersistValue from various Database.Persist.Sql.Orphan.* modules.
  • Batching enhancements to reduce db round-trips.
    • Added getMany and repsertMany for batched get and repsert.
    • Added putMany with a default/slow implementation. SqlBackend’s that support native UPSERT should override this for batching enhancements.
    • Updated insertEntityMany to replace slow looped usage with batched execution.
  • See #770


  • Switch from MonadBaseControl to MonadUnliftIO
  • Reapplies #723, which was reverted in version 2.7.3.

  • Improve error messages when failing to parse database results into Persistent records. #741
  • A handful of fromPersistField implementations called error instead of returning a Left Text. All of the implementations were changed to return Left. #741
  • Improve error message when a SQL insert fails with a custom primary key #757


  • Reverts #723, which generalized functions using the BackendCompatible class. These changes were an accidental breaking change.
  • Recommend the PersistDbSpecific docs if someone gets an error about converting from PersistDbSpecific


  • Many of the functions have been generalized using the BackendCompatible class. #723
    • This change was an accidental breaking change and was reverted in 2.7.3.
    • These change will be released in a future version of Persistent with a major version bump.
  • Add raw sql quasi quoters #717


  • Added an insertUniqueEntity function #718
  • Added BackendCompatible class #701


  • Fix upsert behavior #613
  • Atomic upsert query fixed for arithmatic operations #662
  • Haddock and test coverage improved for upsert


  • Fix edge case for \<-. [Nothing]
  • Introduce connMaxParams
  • Add ‘getJustEntity’ and ‘insertRecord’ convenience function
  • Minor Haddock improvment


  • Add connUpsertSql type for providing backend-specific upsert sql support.


  • read/write typeclass split
  • add insertOrGet convenience function to PersistUnique

  • Documentation updates #515


  • Workaround for side-exiting transformers in runSqlConn #516


  • PersistField instance for Natural
  • better oracle support in odbc


  • Add liftSqlPersistMPool function
  • support http-api-data for url serialization


  • Migration failure message with context
  • Fix insertKey for composite keys


  • Add a RawSql instance for Key. This allows selecting primary keys using functions like rawSql. #407
  • SqlBackend support for an optimized insertMany


Important! If persistent-template is not upgraded to you might need to make sure Int64 is in scope for your model declarations.

  • add showMigration function
  • explicitly use Int64 for foreign key references


Add dbIdColumnsEsc to Sql.Utils. Used in persistent-postgresql


  • Fix getBy with a primary key. #342


  • Break self-referencing cycles in the entity declarations


  • Error with Doubles without a decimal part #378
  • runSqlPool does not perform timeout checks.

  • One extra feature for #939: use logDebugN instead

Parse UTCTime in 8601 format #339

Support for monad-control 1.0