The Prisma schema file (short: schema file, Prisma schema or schema) is the main configuration file for your Prisma setup. It is typically called schema.prisma
and consists of the following parts:
- Data sources: Specify the details of the data sources Prisma should connect to (e.g. a PostgreSQL database)
- Data model definition: Specifies your application models (the shape of the data per data source)
- Generators (optional): Specifies what clients should be generated based on the data model (e.g. Prisma Client JS)
Whenever a prisma2
command is invoked, the CLI typically reads some information from the schema file, e.g.:
prisma2 generate
: Reads all above mentioned information from the Prisma schema to generate the correct data source client code (e.g. Photon.js).prisma2 migrate save --experimental
: Reads the data sources and data model definition to create a new migration.
You can also use environment variables inside the schema file to provide configuration options when a CLI command is invoked.
Here is an example for a schema file that specifies a data source (SQLite), a generator (Prisma Client JS) and a data model definition:
// schema.prisma
datasource sqlite {
url = "file:data.db"
provider = "sqlite"
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id
createdAt DateTime @default(now())
email String @unique
name String?
role Role @default(USER)
posts Post[]
}
model Post {
id Int @id
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
author User
title String
published Boolean @default(false)
}
enum Role {
USER
ADMIN
}
The default name for the schema file is schema.prisma
. When your schema file is named like this, Prisma 2 CLI will detect it automatically in the
directory where you invoke the CLI command.
If the schema file is named differently, you can provide an explicit option to the command to point the CLI to the location of the schema file.
Note: The CLI option to specify the path to the schema file is not yet implemented. You can track the progress of this issue here.
The schema file is written in Prisma Schema Language (PSL). You can find a full reference for PSL in the spec.
A data source can be specified using a datasource
block in the schema file.
Name | Required | Type | Description |
---|---|---|---|
provider |
Yes | Enum (postgresql , mysql , sqlite ) |
Describes which data source connector to use. |
url |
Yes | String (URL) | Connection URL including authentication info. Each data source connector documents the URL syntax. Most connectors use the syntax provided by the database. |
A data source connector may bring its own fields to allow users to tailor their data models according to specific features of the connected data sources.
Data sources are typically named after the provider
:
datasource sqlite {
provider = "sqlite"
url = env("SQLITE_URL")
}
datasource mysql {
provider = "mysql"
url = env("MYSQL_URL")
}
datasource postgresql {
provider = "postgresql"
url = env("POSTGRESQL_URL")
}
This is a general convention, technically data sources can be named anything. Lowercase spelling is typically preferred.
A generator configures what data source clients are generated and how they're generated. Language preferences and configuration will go in here.
Name | Required | Type | Description |
---|---|---|---|
provider |
Yes | String (file path) or Enum (prisma-client-js ) |
Describes which generator to use. This can point to a file that implements a generator or specify a built-in generator directly. |
output |
(optional) | String (file path) | Determines the location for the generated client. |
binaryTargets |
(optional) | List of Enums (prebuilt binaries available here). | Declarative way to download the required binaries. |
- A generator may bring its own fields to allow users to customize the generation behaviour.
- Both
binaryTargets
.
generator js {
provider = "prisma-client-js"
}
generator js_custom_output {
provider = "prisma-client-js"
output = "../src/generated/client"
}
generator ts {
provider = "./path/to/custom/generator"
}
generator ts {
provider = "./path/to/custom/generator"
binaryTargets = ["native", "debian-openssl-1.0.x"]
}
Note: The default
output
for theprisma-client-js
provider is yournode_modules
directory. This can be customized as seen in the second example in the code snippet above.
There are several blocks you can use for data modeling in your schema file:
model
enum
type
There also are attributes and functions you can use to enhance the functionality of your data model definition.
Learn about the data modeling components in detail here.
You can use environment variables to provide configuration options when a CLI command is invoked. This is helpful e.g., to:
- Keep secrets out of the schema file
- Improve portability of the schema file
Environment variables can be provided using the env
function:
datasource pg {
provider = "postgresql"
url = env("DATABASE_URL")
}
There are a few limitations with env
at the moment:
- It is not possible to use string concat operations (e.g. to construct your database connection string).
- It is not possible to use environment variables for the
provider
argument indatasource
andgenerator
definitions.
For many developer tools, it has become a good practice to define environment variables using .env
files.
Prisma provides native support for .env
files if the .env
file is located in the same directory as your Prisma schema file. This means any environment variables defined in that .env
file will automatically be loaded when running a Prisma CLI command.
WARNING: Do not commit your
.env
files into version control.
For example, it is a common scenario to set your database connection URL via an environment variable:
// schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
This requires the DATABASE_URL
to be set in your .env
file:
# .env
DATABASE_URL=postgresql://test:test@localhost:5432/test?schema=public
When running any command that needs to access the database defined via the datasource
block (e.g. prisma2 introspect
), the Prisma CLI automatically loads the DATABASE_URL
environment variables from the .env
file and makes it available to the CLI.
If you want environment variables to be evaluated at runtime, you need to load them manually in your application code, e.g. using dotenv
:
import * as dotenv from 'dotenv'
dotenv.config() // load the environment variables
console.log(`The connection URL is ${process.env.DATABASE_URL}`)
There are two types of comments that are supported in the schema file:
// comment
: This comment is for the reader's clarity and is not present in the AST of the schema file./// comment
: These comments will show up in the AST of the schema file, either as descriptions to AST nodes or as free-floating comments. Tools can then use these comments to provide additional information to the user.
Here are some different examples:
/// This comment will get attached to the `User` node
model User {
/// This comment will get attached to the `id` node
id Int
// This comment is just for you
weight Float /// This comment gets attached to the `weight` node
}
// This comment is just for you. This comment will not
// show up in the AST.
/// This is a free-floating comment that will show up
/// in the AST as a `Comment` node, but is not attached
/// to any other node. We can use these for documentation
/// in the same way that godoc.org works.
model Customer {}
Following the lead of gofmt and prettier, PDL syntax ships with a formatter for
.prisma
files.
Like gofmt
and unlike prettier
, there are no options for configuration here. There is exactly one way to format a prisma file.
This strictness serves two benefits:
- No bikeshedding. There's a saying in the Go community that, "Gofmt's style is nobody's favorite, but gofmt is everybody's favorite."
- No pull requests with different spacing schemes.
block _ {
key = "value"
key2 = 1
long_key = true
}
Formatting may be reset by a newline:
block _ {
key = "value"
key2 = 1
key10 = true
long_key = true
long_key_2 = true
}
Multiline objects follow their own nested formatting rules:
block _ {
key = "value"
key2 = 1
key10 = {
a = "a"
b = "b"
}
key10 = [
1,
2
]
}
block _ {
id String @id
first_name LongNumeric @default
}
Multiline field attributes are properly aligned with the rest of the field attributes:
block _ {
id String @id
@default
first_name LongNumeric @default
}
Formatting may be reset by a newline:
block _ {
id String @id
@default
first_name LongNumeric @default
}