HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Modulepersistent-2.14.6.3Haskell2010

Database.Persist.Class.PersistEntity

  • 7 types
  • 3 classes
  • 11 values
classclass (PersistField (Key record), ToJSON (Key record), FromJSON (Key record), Show (Key record), Read (Key record), Eq (Key record), Ord (Key record)) => PersistEntity record where
#

Persistent serialized Haskell records to the database. A Database Entity (A row in SQL, a document in MongoDB, etc) corresponds to a Key plus a Haskell record.

For every Haskell record type stored in the database there is a corresponding PersistEntity instance. An instance of PersistEntity contains meta-data for the record. PersistEntity also helps abstract over different record types. That way the same query interface can return a PersistEntity, with each query returning different types of Haskell records.

Some advanced type system capabilities are used to make this process type-safe. Persistent users usually don't need to understand the class associated data and functions.

Associated types

  • type family PersistEntityBackend record

    Persistent allows multiple different backends (databases).

  • data family Key record

    By default, a backend will automatically generate the key Instead you can specify a Primary key made up of unique values.

  • data family EntityField record :: Type -> Type

    An EntityField is parameterised by the Haskell record it belongs to and the additional type of that field.

    As of persistent-2.11.0.0, it's possible to use the OverloadedLabels language extension to refer to EntityField values polymorphically. See the documentation on SymbolToField for more information.

  • data family Unique record

    Unique keys besides the Key.

Methods

valuetabulateEntity
  1. :: PersistEntity record
  2. => forall a. EntityField record a -> a
  3. -> Entity record
#

Construct an Entity record by providing a value for each of the record's fields.

These constructions are equivalent:

entityMattConstructor, entityMattTabulate :: Entity User
entityMattConstructor =
    Entity
        { entityKey = toSqlKey 123
        , entityVal =
            User
                { userName = Matt
                , userAge = 33
                }
        }

entityMattTabulate =
    tabulateEntity $ \case
        UserId ->
            toSqlKey 123
        UserName ->
            Matt
        UserAge ->
            33

This is a specialization of tabulateEntityA, which allows you to construct an Entity by providing an Applicative action for each field instead of a regular function.

datadata Filter record
#

Filters which are available for select, updateWhere and deleteWhere. Each filter constructor specifies the field being filtered on, the type of comparison applied (equals, not equals, etc) and the argument for the comparison.

Persistent users use combinators to create these.

Note that it's important to be careful about the PersistFilter that you are using, if you use this directly. For example, using the In PersistFilter requires that you have an array- or list-shaped EntityField. It is possible to construct values using this that will create malformed runtime values.

Constructors

datadata Entity record
#

Datatype that represents an entity, with both its Key and its Haskell record representation.

When using a SQL-based backend (such as SQLite or PostgreSQL), an Entity may take any number of columns depending on how many fields it has. In order to reconstruct your entity on the Haskell side, persistent needs all of your entity columns and in the right order. Note that you don't need to worry about this when using persistent's API since everything is handled correctly behind the scenes.

However, if you want to issue a raw SQL command that returns an Entity, then you have to be careful with the column order. While you could use SELECT Entity.* WHERE ... and that would work most of the time, there are times when the order of the columns on your database is different from the order that persistent expects (for example, if you add a new field in the middle of you entity definition and then use the migration code -- persistent will expect the column to be in the middle, but your DBMS will put it as the last column). So, instead of using a query like the one above, you may use rawSql (from the Database.Persist.Sql module) with its /entity selection placeholder/ (a double question mark ??). Using rawSql the query above must be written as SELECT ?? WHERE ... Then rawSql will replace ?? with the list of all columns that we need from your entity in the right order. If your query returns two entities (i.e. (Entity backend a, Entity backend b)), then you must you use SELECT ??, ?? WHERE ..., and so on.

Constructors

Instances10Eq, Ord, Read, Show, Generic, SafeToInsert, …
valuekeyValueEntityToJSON
  1. :: (PersistEntity record, ToJSON record)
  2. => Entity record
  3. -> Value
#

Predefined toJSON. The resulting JSON looks like {"key": 1, "value": {"name": ...}}.

The typical usage is:

instance ToJSON (Entity User) where
    toJSON = keyValueEntityToJSON
valueentityIdToJSON
  1. :: (PersistEntity record, ToJSON record)
  2. => Entity record
  3. -> Value
#

Predefined toJSON. The resulting JSON looks like {"id": 1, "name": ...}.

The typical usage is:

instance ToJSON (Entity User) where
    toJSON = entityIdToJSON

PersistField based on other typeclasses

4 declarations

Convenience function for getting a free PersistField instance from a type with JSON instances. The JSON parser used will accept JSON values other that object and arrays. So, if your instance serializes the data to a JSON string, this will still work.

Example usage in combination with toPersistValueJSON:

instance PersistField MyData where
  fromPersistValue = fromPersistValueJSON
  toPersistValue = toPersistValueJSON
valuetoPersistValueEnum :: Enum a => a -> PersistValue
#

Convenience function for getting a free PersistField instance from a type with an Enum instance. The function derivePersistField from the persistent-template package should generally be preferred. However, if you want to ensure that an ORDER BY clause that uses your field will order rows by the data constructor order, this is a better choice.

Example usage in combination with fromPersistValueEnum:

data SeverityLevel = Low | Medium | Critical | High
  deriving (Enum, Bounded)
instance PersistField SeverityLevel where
  fromPersistValue = fromPersistValueEnum
  toPersistValue = toPersistValueEnum

Convenience function for getting a free PersistField instance from a type with an Enum instance. This function also requires a Bounded instance to improve the reporting of errors.

Example usage in combination with toPersistValueEnum:

data SeverityLevel = Low | Medium | Critical | High
  deriving (Enum, Bounded)
instance PersistField SeverityLevel where
  fromPersistValue = fromPersistValueEnum
  toPersistValue = toPersistValueEnum

Support for OverloadedLabels with EntityField

1 declaration
classclass SymbolToField (sym :: Symbol) rec typ | sym rec -> typ where
#

This type class is used with the OverloadedLabels extension to provide a more convenient means of using the EntityField type. EntityField definitions are prefixed with the type name to avoid ambiguity, but this ambiguity can result in verbose code.

If you have a table User with a name Text field, then the corresponding EntityField is UserName. With this, we can write #name :: EntityField User Text.

What's more fun is that the type is more general: it's actually #name :: (SymbolToField "name" rec typ) => EntityField rec typ

Which means it is *polymorphic* over the actual record. This allows you to write code that can be generic over the tables, provided they have the right fields.

Methods

Safety check for inserts

2 declarations
classclass SafeToInsert a
#

A type class which is used to witness that a type is safe to insert into the database without providing a primary key.

The TemplateHaskell function mkPersist will generate instances of this class for any entity that it works on. If the entity has a default primary key, then it provides a regular instance. If the entity has a Primary natural key, then this works fine. But if the entity has an Id column with no default=, then this does a TypeError and forces the user to use insertKey.

Instances2SafeToInsert
  • TypeError (EntityErrorMessage a) => SafeToInsert (Entity a)Defined in persistent-2.14.6.3 · Database.Persist.Class.PersistEntity
  • TypeError (FunctionErrorMessage a b) => SafeToInsert (a -> b)Defined in persistent-2.14.6.3 · Database.Persist.Class.PersistEntity