Overview

The data model definition defines your application models (also called Prisma models). These models represent the entities of your application domain and map to the tables in your database.

Models are the foundation for all available queries in the Prisma Client API. When used with TypeScript, Prisma Client provides generated type definitions for your models and any variations of them to make database access entirely type safe.

Application domain examples

A few examples for application domains and "typical" models are:

  • In a blogging application you probably have models like Blog, Author, Article and Comment.
  • In an e-commerce application you probably have models like Customer, Order, Item and Invoice.
  • In a social media application you probably have models like User, Post, Photo and Message.

Technical purpose of Prisma models

On a technical level, models serve two main purposes:

  • They represent the tables in the underlying database.
  • They are the foundation for the available queries in the generated Prisma Client API.

Data modeling primitives

You can create your data model using the following primitives:

  • model: Defines a Prisma model
  • enum: Defines an enum (only available if enums are supported natively by your database)

Additionally, you can configure your models with attributes and functions.

Example

1datasource postgresql {
2 provider = "postgresql"
3 url = env("DATABASE_URL")
4}
5
6generator client {
7 provider = "prisma-client-js"
8}
9
10model User {
11 id Int @id @default(autoincrement())
12 email String @unique
13 name String?
14 role Role @default(USER)
15 posts Post[]
16 profile Profile?
17}
18
19model Profile {
20 id Int @id @default(autoincrement())
21 bio String
22 user User @relation(fields: [userId], references: [id])
23 userId Int
24}
25
26model Post {
27 id Int @id @default(autoincrement())
28 createdAt DateTime @default(now())
29 title String
30 published Boolean @default(false)
31 author User @relation(fields: [authorId], references: [id])
32 authorId Int
33 categories Category[] @relation(references: [id])
34}
35
36model Category {
37 id Int @id @default(autoincrement())
38 name String
39 posts Post[] @relation(references: [id])
40}
41
42enum Role {
43 USER
44 ADMIN
45}

Introspection vs Prisma Migrate

Depending on the use case, the data model is typically created in either of two ways:

  • Manually written: You can write your data model manually and map it to your database using Prisma Migrate (experimental). In this case, the data model is the single source of truth for the models of your application.
  • Generated from introspection: When you have an existing database or prefer migrating your database schema with SQL, you generate the data model by introspecting your database. In this case, the database schema is the single source of truth for the models of your application.

Note: Since Prisma Migrate is currently in an experimental state, the officially recommended way for using Prisma is the introspection-based approach.

Models

You can find information about models here.

Scalar types

You can use the following scalar types in the Prisma data model:

Prisma TypeDescription
StringVariable length text
BooleanTrue or false value
IntInteger value
FloatFloating point number
DateTimeTimestamp
JsonA JSON object literal

The data source connector determines what native database type each of these types map to. Similarly, the generator determines what type in the target programming language each of these types map to.

Expand below to see the mappings per connector and generator.


Connectors

TypePostgreSQLMySQLSQLiteRaw JSON
StringtextTEXTTEXTstring
BooleanbooleanBOOLEANn/aboolean
IntintegerINTINTEGERnumber
FloatrealFLOATREALnumber
DateTimetimestampTIMESTAMPn/an/a
Jsonjson / jsonbJSONn/aobject

Generators

TypePrisma Client
Stringstring
Booleanboolean
Intnumber
Floatnumber
DateTimeDate
JSONobject

Enums

You can define enums in your data model if they're supported by the data source you use:

Enums are considered scalar types in the Prisma data model. They're therefore by default included as return values in Prisma Client queries.

Enums are defined via the enum block.

Naming enums

Enum names must start with a letter. They are typically spelled in PascalCase and use the singular form (e.g. Role instead of role, roles or Roles).

Technically, an enum can be named anything that adheres to this regular expression:

1[A-Za-z][A-Za-z0-9_]*

Examples

Specify an enum with two possible values

1enum Role {
2 USER
3 ADMIN
4}
5
6model User {
7 id Int @id @default(autoincrement())
8 role Role
9}

Specify an enum with two possible values and set a default value

1enum Role {
2 USER
3 ADMIN
4}
5
6model User {
7 id Int @id @default(autoincrement())
8 role Role @default(USER)
9}

Attributes

Attributes modify the behavior of a field or block (e.g. models). There are two ways to add attributes to your data model:

  • Field attributes are prefixed with @
  • Block attributes are prefixed with @@

Overview

Here's a quick overview of the available field attributes:

NameDatabase representationArgumentsDescription
@idPRIMARY KEY-Defines a single-field ID on the model.
@@idPRIMARY KEYA list of field referencesDefines a multi-field ID on the model.
@defaultDEFAULTAn expression (e.g. 5, true, now())Defines a default value for this field. @default takes an expression as an argument.
@uniqueUNIQUE-Defines a unique constraint for this field.
@@uniqueUNIQUEA list of field referencesDefines a compound unique constraint for the specified fields.
@@indexINDEXA list of field referencesDefines an index.
@relationFOREIGN KEY / REFERENCESA name and/or a list of field referencesDefines meta information about the relation. Learn more.
@mapn/aThe name of the target database columnMaps a field name from the Prisma schema to a different column name.
@@mapn/aThe name of the target database tableMaps a model name from the Prisma schema to a different table name.
@updatedAtn/a-Automatically stores the time when a record was last updated.

Here's an overview of the exact signatures of all attributes:

1// IDs
2@id
3@@id(_ fields: FieldReference[])
4
5// Unique
6@unique
7@@unique(_ fields: FieldReference[])
8
9// Default
10@default(_ expression: Expression)
11
12// Index
13@@index(_ fields: FieldReference[])
14
15// Mapping model/field names from Prisma schema to database
16@map(_ name: String)
17@@map(_ name: String)
18
19// Configuring relations
20@relation(_ name: String?, fields: FieldReference[]?, references: FieldReference[]?)

Note: The leading underscore in a signature means the argument name can be omitted (read more below).

Here's an overview of the types that are used in the attribute signatures:

TypeDescriptionExample
FieldReference[]An array of field names[id], [firstName, lastName]
StringA variable length text in double quotes"", "Hello World", "Alice"
ExpressionAn expression that can be evaluated by Prisma42.0, "", Bob, now(), cuid()

Arguments

Note that some attributes take arguments. Arguments in attributes are always named, but in most cases the argument name can be omitted.

The following pairs of default values are all equivalent.

The name of the fields argument on the @@id attribute can be omitted

1@@id(fields: [title, author])
2@@id([title, author])

The name of the value argument on the @default attribute can be omitted

1id Int @id @default(value: autoincrement())
2id Int @id @default(autoincrement())

The name of the fields argument on the @@unique attribute can be omitted

1@@unique(fields: [title, author])
2@@unique([title, author])

The name of the fields argument on the @@index attribute can be omitted

1@@index(fields: [title, author])
2@@index([title, author])

The name of the name argument on the @relation attribute can be omitted (references is required though)

1@relation(name: "UserOnPost", references: [id])
2@relation("UserOnPost", references: [id])
3
4// or
5
6@relation(name: "UserOnPost")
7@relation("UserOnPost")

The name of the name argument on the @map and @@map attributes can be omitted

1@map(name: "is_admin")
2@map("is_admin")
3
4// and
5
6@@map(name: "users")
7@@map("users")

IDs

You can add IDs to your models to be able to uniquely identify individual records of that model. In relational databases, this ID corresponds to a PRIMARY KEY constraint.

IDs can be defined on a single field using @id or on multiple fields (also called composite or compound IDs) using @@id. Any model can at most have one ID, no matter if it's defined on a single field or on multiple fields.

Signature

The signatures of the @id attribute looks as follows:

1@id

The signatures of the @@id attribute looks as follows:

1@@id(_ fields: FieldReference[])

Single-field IDs

To determine which field of a model represents the ID, you can annotate it with the @id attribute. Note that a field that's annotated with @id can not be optional.

@id attributes can be defined on fields of any type in your Prisma schema (e.g. Int, String, enums, relation fields, ...). The only exception are "virtual" relation fields that are defined only on a Prisma-level but do not manifest in the database.

Single-field IDs without default values
1model User {
2 id String @id
3 name String
4}

Note that in the above case, you must provide your own ID values when creating new records for the User model using Prisma Client, e.g.:

1const newUser = await prisma.user.create({
2 data: {
3 id: 1,
4 name: 'Alice',
5 },
6})
Single-field IDs with default values

In most cases, you want to have the ID initialized by your database. To do so, you can annotate it with the @default attribute and initialize the field with a function.

These are the available functions and the types they're compatible with:

FunctionTypeDescription
autoincrement()IntCreate a sequence of integers in the underlying database and assign the incremented values to the ID values of the created records based on the sequence.
cuid()StringGenerate a globally unique identifier based on the cuid spec.
uuid()StringGenerate a globally unique identifier based on the UUID spec.

Note that using these functions will have different effects with respect to your database and Prisma internals:

FunctionPostgreSQLMySQLSQLitePrisma
cuid()n/an/an/aImplemented by query engine
uuid()n/an/an/aImplemented by query engine
autoincrement()Uses the SERIAL typeUses the AUTO_INCREMENT attributeUses the AUTOINCREMENT keywordn/a

This table shows how each of these functions is implemented.

cuid() and uuid() are implemented by Prisma and therefore are not "visible" in the underlying database schema. You can still use them when using introspection by manually changing your Prisma schema and generating Prisma Client, in that case the values will be generated by Prisma's query engine.

autoincrement() on the other hand is always "implememented" on the database-level, meaning it does manifest in the database schema and can be recognized through introspection.

Examples

Specify an ID on String without a default value

1model User {
2 id String @id
3 name String
4}

Specify an ID on field authorId without a default value

1model Post {
2 authorId Int @id
3 author User @relation(fields: [authorId], references: [id])
4 title String
5 published Boolean @default(false)
6}
7
8model User {
9 email String @unique
10 name String?
11 posts Post[]
12}

Note that in this case you can only create new Post records by using Prisma Client's nested writes to immediately connect the new Post record with a new or existing User record, e.g.:

1const post = await prisma.post.create({
2 data: {
3 title: 'Hello World',
4 author: {
5 create: {
6 name: 'Alice',
7 email: 'alice@prisma.io',
8 },
9 },
10 },
11})

Or when a User record with bob@prisma.io as its email already exists, you can connect it to the new Post record in a nested write:

1const post = await prisma.post.create({
2 data: {
3 title: 'Hello World',
4 author: {
5 connect: {
6 email: 'bob@prisma.io',
7 },
8 },
9 },
10})

Generate cuid() values as IDs

1model User {
2 id String @id @default(cuid())
3 name String
4}

Generate uuid() values as IDs

1model User {
2 id String @id @default(uuid())
3 name String
4}

Generate auto-incrementing integers as IDs

1model User {
2 id Int @id @default(autoincrement())
3 name String
4}

Multi-field IDs

To determine which fields of a model represent the multi-field ID, you can include them in the @@id attribute that's defined on your model.

@@id attributes can include fields of any type in your Prisma schema (e.g. Int, String, enums, relation fields, ...).

Examples

Specify a multi-field ID on two String fields

1model User {
2 firstName String
3 lastName String
4 email String @unique
5 isAdmin Boolean @default(false)
6
7 @@id([firstName, lastName])
8}

When creating new User records, you now must provide a unique combination of values for firstName and lastName:

1const user = await prisma.user.create({
2 data: {
3 firstName: 'Alice',
4 lastName: 'Smith',
5 },
6})

Specify a multi-field ID on two String fields and one Boolean field

1model User {
2 firstName String
3 lastName String
4 email String @unique
5 isAdmin Boolean @default(false)
6
7 @@id([firstName, lastName, isAdmin])
8}

When creating new User records, you now must provide a unique combination of values for firstName, lastName and isAdmin:

1const user = await prisma.user.create({
2 data: {
3 firstName: 'Alice',
4 lastName: 'Smith',
5 isAdmin: true,
6 },
7})

Specify a multi-field ID that includes a relation field

1model Post {
2 title String
3 published Boolean @default(false)
4 author User @relation(fields: [authorId], references: [id])
5 authorId Int
6
7 @@id([authorId, title])
8}
9
10model User {
11 id Int @default(autoincrement())
12 email String @unique
13 name String?
14 posts Post[]
15}

When creating new Post records, you now must provide a unique combination of values for authorId (foreign key) and title:

1const post = await prisma.post.create({
2 data: {
3 title: 'Hello World',
4 author: {
5 connect: {
6 email: 'alice@prisma.io',
7 },
8 },
9 },
10})

Unique

You can add unique attributes to your models to be able to uniquely identify individual records of that model. In relational databases, this corresponds to adding a UNIQUE constraint.

Unique attributes can be defined on a single field using @unique or on multiple fields (also called composite or compound unique constraints) using @@unique. A model can have any number of unique attributes.

Note: Adding a unique constraint automatically adds a corresponding unique index to the specified column(s).

Signature

The signatures of the @unique attribute looks as follows:

1@unique

The signatures of the @@unique attribute looks as follows:

1@@unique(_ fields: FieldReference[])

Single-field unique attributes

To add a unique attribute to a field of a model, you can annotate it with the @unique attribute. A field that's annotated with @unique can be optional or required. If the field is optional, null values are always considered to be distinct from each other and any other values.

The only exception where a field annotated with @unique must be required is when it is the only unique constraint on a model that has no ID:

1model User {
2 email String @unique // `email` can not be optional because it's the only unique field on the model
3 name String?
4}

@unique attributes can be defined on fields of any type in your Prisma schema (e.g. Int, String, enums, relation fields, ...). The only exception are "virtual" relation fields that are defined only on a Prisma-level but do not manifest in the database.

Examples

Specify a unique attribute on a required String field

1model User {
2 email String @unique
3 name String
4}

Specify a unique attribute on an optional String field

1model User {
2 id Int @id @default(autoincrement())
3 email String? @unique
4 name String
5}

Note that in this case, it is allowed to have multiple User records in the database where the email is NULL because NULL values are considered to distinct from each other.

Specify a unique attribute on relation scalar field authorId

1model Post {
2 author User @relation(fields: [authorId], references: [id])
3 authorId Int @unique
4 title String
5 published Boolean @default(false)
6}
7
8model User {
9 id Int @id @default(autoincrement())
10 email String? @unique
11 name String
12 Post Post[]
13}

Specify a unique attribute with cuid() values as default values

1model User {
2 id String @unique @default(cuid())
3 name String
4}

Multi-field unique attributes

To add multi-field unique attribue to a model, you have to annotate it with the @@unique attribute and provide the list of referenced fields as an argument.

@@unique attributes can include fields of any type in your Prisma schema (e.g. Int, String, enums, relation fields, ...).

Examples

Specify a multi-field unique attribute on two String fields

1model User {
2 id Int @default(autoincrement())
3 firstName String
4 lastName String
5 isAdmin Boolean @default(false)
6
7 @@unique([firstName, lastName])
8}

Specify a multi-field unique attribute on two String fields and one Boolean field

1model User {
2 id Int @default(autoincrement())
3 firstName String
4 lastName String
5 isAdmin Boolean @default(false)
6
7 @@unique([firstName, lastName, isAdmin])
8}

Specify a multi-field unique attribute that includes a relation field

1model Post {
2 id Int @default(autoincrement())
3 author User @relation(fields: [authorId], references: [id])
4 authorId Int
5 title String
6 published Boolean @default(false)
7
8 @@unique([authorId, title])
9}
10
11model User {
12 id Int @id @default(autoincrement())
13 email String @unique
14 posts Post[]
15}

Default values

You can define default values for the fields of your models using the @default attribute. @default attributes are typically represented by DEFAULT values in the underlying database (with a few exceptions like cuid() and uuid() which are provided by Prisma's query engine and are therefore not "visible" in the underlying database schema).

The @default attribute takes as argument an expression, this can be a static, hardcoded value e.g. 5, true, "Hello" or a function, e.g. now(), uuid(), cuid(). Note that there is a special function in the Prisma schema called dbgenerated() which is used in introspection results for default values that can not yet be represented in the Prisma schema.

Default values can be defined on any scalar type but not on relation fields.

Signature

The signatures of the @default attribute looks as follows:

1@default(_ expression: Expression)

Static default values

For scalar types, you can use any static value that corresponds to the type of a field as a default value:

TypeExamples
Int-100, 0, 42
Float-100.5, 0, 4.2
String"Alice", "Hello World", ""
Booleantrue, false
DateTime"2020-03-19T14:21:00+0200"

Note that static default values for DateTime are based on the ISO 8601 standard. However, they must always include the time including the time offsets from UTC.

Similarly, you can define default values for enums. Assume you have the following enum definition:

1enum Role {
2 USER
3 ADMIN
4}

In that case, you have two possible values as default values:

TypeExamples
RoleADMIN, CUSTOMER

Functions as default values

These are the available functions and the types they're compatible with:

FunctionTypeDescription
autoincrement()IntCreate a sequence of integers in the underlying database and assign the incremented values to the ID values of the created records based on the sequence.
now()DateTimeSet a timestamp of the time when a record is created.
cuid()StringGenerate a globally unique identifier based on the cuid spec.
uuid()StringGenerate a globally unique identifier based on the UUID spec.
dbgenerated()AnyRepresents default values that can't be expressed in the Prisma schema. Only available after introspection.

Note that using these functions will have different effects with respect to your database and Prisma internals:

FunctionPostgreSQLMySQLSQLitePrisma
cuid()n/an/an/aImplemented by query engine
uuid()n/an/an/aImplemented by query engine
autoincrement()Uses the SERIAL typeUses the AUTO_INCREMENT attributeUses the AUTOINCREMENT keywordn/a
now()CURRENT_TIMESTAMP and aliases like now()CURRENT_TIMESTAMP and aliases like now()CURRENT_TIMESTAMP and aliases like date('now')
dbgenerated()Any expressionAny expressionAny expressionn/a

This table shows how each of these functions is implemented.

cuid() and uuid() are implemented by Prisma and therefore are not "visible" in the underlying database schema. You can still use them when using introspection by manually changing your Prisma schema and generating Prisma Client, in that case the values will be generated by Prisma's query engine

autoincrement(), now and dbgenerated() on the other hand are always "implemented" on the database-level, meaning they manifest in the database schema and can be recognized through introspection.

Examples

Default value for an Int

1model User {
2 email String @unique
3 profileViews Int @default(0)
4}

Default value for a Float

1model User {
2 email String @unique
3 number Float @default(1.1)
4}

Default value for a String

1model User {
2 email String @unique
3 name String @default("")
4}

Default value for a Boolean

1model User {
2 email String @unique
3 isAdmin Boolean @default(false)
4}

Default value for a DateTime

Note that static default values for DateTime are based on the ISO 8601 standard. However, they must always include the time including the time offsets from UTC.

1model User {
2 email String @unique
3 data DateTime @default("2020-03-19T14:21:00+0200")
4}

Limitations

Default values are currently not allowed on relation fields in the Prisma schema. Note however that you can still define default values manually in the underlying database using plain SQL. These will not be represented in the Prisma schema though, this is a temporary limitation which you can track on GitHub.

Indexes

You can define indexes on one or multiple fields of your models via the @@index on a model.

Signature

The signature of the @@index attribute looks as follows:

1@@index(_ fields: FieldReference[])

Examples

Assume you want to add an index for the title field of the Post model from the example above. You can define the index like so:

1model Post {
2 id Int @id @default(autoincrement())
3 title String
4 content String?
5
6 @@index([title])
7}

To define an index on multiple fields (i.e. a multi-column index), you can add more fields to the array passed to the @@index attribute, e.g.:

1model Post {
2 id Int @id @default(autoincrement())
3 title String
4 content String?
5
6 @@index([title, content])
7}

Limitations

It is currently not possible to provide more configuration options to the index:

  • PostgreSQL
    • Define index fields as expressions (e.g. CREATE INDEX title ON public."Post"((lower(title)) text_ops);)
    • Specify index methods with USING; PostgreSQL supports these index methods: B-tree, hash, GiST, and GIN; Prisma uses B-Tree by default
    • Define partial indexes with WHERE
    • Create indexes concurrently with CONCURRENTLY
  • MySQL
    • Specify index methods with USING; MySQL supports these index methods: B-tree, hash; Prisma uses B-Tree by default

Note that while you can't configure these option in your Prisma schema, you can still configure them on the database-level directly.

Mapping column, table and enum names

You can use the @map and @@map attributes to map field, model and enum names as well in your Prisma schema to different column and table names in the underlying database schema.

Read more about this on the Configuring the Prisma Client API page.

Signature

The signature of the @map attribute looks as follows:

1@map(_ name: String)

The signature of the @@map attribute looks as follows:

1@@map(_ name: String)

Examples

Map the User model to a table called users:

1model User {
2 id Int @id @default(autoincrement())
3 name String
4 @@map("users")
5}

Map the firstName field to a column called first_name:

1model User {
2 id Int @id @default(autoincrement())
3 firstName String @map("first_name")
4}

Map the User model to a table called users and firstName field to a column called first_name:

1model User {
2 id Int @id @default(autoincrement())
3 firstName String @map("first_name")
4 @@map("users")
5}

Map the Role enum to a native enum in the database called _Role its values to lowercase values in the database:

1enum Role {
2 ADMIN @map("admin")
3 CUSTOMER @map("customer")
4
5 @@map("_Role")
6}

Configuring relations

You can learn everything about configuration relations on the Relations page in the docs.

Functions

The Prisma schema supports a number of functions. These can be used to specify default values on fields of a model. You can find a reference for all available functions here.

Edit this page on Github