persistent-1.3.3: Type-safe, multi-backend data serialization.

Safe HaskellNone




data Checkmark Source

A Checkmark should be used as a field type whenever a uniqueness constraint should guarantee that a certain kind of record may appear at most once, but other kinds of records may appear any number of times.

NOTE: You need to mark any Checkmark fields as nullable (see the following example).

For example, suppose there's a Location entity that represents where a user has lived:

     user    UserId
     name    Text
     current Checkmark nullable

UniqueLocation user current

The UniqueLocation constraint allows any number of Inactive Locations to be current. However, there may be at most one current Location per user (i.e., either zero or one per user).

This data type works because of the way that SQL treats NULLable fields within uniqueness constraints. The SQL standard says that NULL values should be considered different, so we represent Inactive as SQL NULL, thus allowing any number of Inactive records. On the other hand, we represent Active as TRUE, so the uniqueness constraint will disallow more than one Active record.

Note: There may be DBMSs that do not respect the SQL standard's treatment of NULL values on uniqueness constraints, please check if this data type works before relying on it.

The SQL BOOLEAN type is used because it's the smallest data type available. Note that we never use FALSE, just TRUE and NULL. Provides the same behavior Maybe () would if () was a valid PersistField.



When used on a uniqueness constraint, there may be at most one Active record.


When used on a uniqueness constraint, there may be any number of Inactive records.

data WhyNullable Source

The reason why a field is nullable is very important. A field that is nullable because of a Maybe tag will have its type changed from A to Maybe A. OTOH, a field that is nullable because of a nullable tag will remain with the same type.

data EntityDef sqlType Source


Functor EntityDef 
Eq sqlType => Eq (EntityDef sqlType) 
Ord sqlType => Ord (EntityDef sqlType) 
Read sqlType => Read (EntityDef sqlType) 
Show sqlType => Show (EntityDef sqlType) 

newtype DBName Source




unDBName :: Text

data FieldDef sqlType Source




fieldHaskell :: !HaskellName

name of the field

fieldDB :: !DBName
fieldType :: !FieldType
fieldSqlType :: !sqlType
fieldAttrs :: ![Attr]

user annotations for a field

fieldStrict :: !Bool

a strict field in the data type. Default: true

fieldEmbedded :: Maybe (EntityDef ())

indicates that the field uses an embedded entity


Functor FieldDef 
Eq sqlType => Eq (FieldDef sqlType) 
Ord sqlType => Ord (FieldDef sqlType) 
Read sqlType => Read (FieldDef sqlType) 
Show sqlType => Show (FieldDef sqlType) 

newtype ZT Source

Avoid orphan instances.


ZT ZonedTime 


data PersistValue Source

A raw value which can be stored in any backend and can be marshalled to and from a PersistField.


PersistText Text 
PersistByteString ByteString 
PersistInt64 Int64 
PersistDouble Double 
PersistRational Rational 
PersistBool Bool 
PersistDay Day 
PersistTimeOfDay TimeOfDay 
PersistUTCTime UTCTime 
PersistZonedTime ZT 
PersistList [PersistValue] 
PersistMap [(Text, PersistValue)] 
PersistObjectId ByteString

Intended especially for MongoDB backend

PersistDbSpecific ByteString

Using PersistDbSpecific allows you to use types specific to a particular backend For example, below is a simple example of the PostGIS geography type:

 data Geo = Geo ByteString

instance PersistField Geo where
   toPersistValue (Geo t) = PersistDbSpecific t

fromPersistValue (PersistDbSpecific t) = Right $ Geo $ Data.ByteString.concat [', t, ']
   fromPersistValue _ = Left Geo values must be converted from PersistDbSpecific

instance PersistFieldSql Geo where
   sqlType _ = SqlOther GEOGRAPHY(POINT,4326)

toPoint :: Double -> Double -> Geo
 toPoint lat lon = Geo $ Data.ByteString.concat ['POINT(, ps $ lon,  , ps $ lat, )']
   where ps = Data.Text.pack . show

If Foo has a geography field, we can then perform insertions like the following:

 insert $ Foo (toPoint 44 44)

data SqlType Source

A SQL data type. Naming attempts to reflect the underlying Haskell datatypes, eg SqlString instead of SqlVarchar. Different SQL databases may have different translations for these types.

newtype KeyBackend backend entity Source




unKey :: PersistValue


Eq (KeyBackend backend entity) 
Ord (KeyBackend backend entity) 
Read (KeyBackend backend entity) 
Show (KeyBackend backend entity) 
ToJSON (KeyBackend backend entity) 
FromJSON (KeyBackend backend entity) 
PathPiece (KeyBackend SqlBackend entity) 
PersistField (KeyBackend backend entity) 
PersistFieldSql (KeyBackend SqlBackend a) 

type family KeyEntity key Source

data Update record Source

updataing a database entity

Persistent users use combinators to create these


forall typ . PersistField typ => Update 
BackendUpdate (BackendSpecificUpdate (PersistEntityBackend record) record) 

data SelectOpt record Source

query options

Persistent users use these directly


forall typ . Asc (EntityField record typ) 
forall typ . Desc (EntityField record typ) 
OffsetBy Int 
LimitTo Int 

type family BackendSpecificFilter backend record Source

data Filter record Source

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


forall typ . PersistField typ => Filter 


filterField :: EntityField record typ
filterValue :: Either typ [typ]
filterFilter :: PersistFilter
FilterAnd [Filter record]

convenient for internal use, not needed for the API

FilterOr [Filter record] 
BackendFilter (BackendSpecificFilter (PersistEntityBackend record) record) 

type Key record = KeyBackend (PersistEntityBackend record) recordSource

Helper wrapper, equivalent to Key (PersistEntityBackend val) val.

Since 1.1.0

data Entity entity Source

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.GenericSql 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.




entityKey :: Key entity
entityVal :: entity


Eq entity => Eq (Entity entity) 
Ord entity => Ord (Entity entity) 
Read entity => Read (Entity entity) 
Show entity => Show (Entity entity) 
PersistField entity => PersistField (Entity entity) 
PersistField entity => PersistFieldSql (Entity entity) 
PersistEntity a => RawSql (Entity a)