The Prisma schema file (short: schema file, Prisma schema or just 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. Photon 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 lift save
: 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 a simple example for a schema file that specifies a data source (SQLite), a generator (Photon JS) and a simple data model definition:
// schema.prisma
datasource mysql {
url = "file:data.db"
provider = "sqlite"
}
generator photonjs {
provider = "photonjs"
}
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, the 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. |
enabled |
No | Boolean | Use environment variables to enable/disable a data source. Default: true . |
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 according to 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")
}
// Note: MongoDB is currently not supported with Prisma 2, but will be soon.
datasource mongo {
provider = "mongo"
url = env("MONGO_URL")
}
This is just a general convention, technically data sources can be named anything. Lowercase spelling is typically preferred. There might be special circumstances, such as switching data sources based on environments, when it can make sense to apply a different naming scheme.
datasource pg {
provider = "postgresql"
url = env("POSTGRESQL_URL")
enabled = true
}
datasource mysql {
provider = "mysql"
url = env("MYSQL_URL")
}
// Note: MongoDB is currently not supported with Prisma 2, but will be soon.
datasource mongo {
provider = "mongodb"
url = env("MONGO_URL")
}
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 (photonjs , nexus-prisma ) |
Describes which generator to use. This can point to a file that implements a generator or specify a built-in generator directly. |
output |
Yes | String (file path) | Determines the location for the generated client. |
platforms |
(optional) | List of Enums (prebuilt binaries available here) or Strings (path to custom binary) | Declarative way to download the required binaries. |
pinnedPlatform |
(optional) | String (pointing to the platform) | Declarative way to choose the runtime binary |
- A generator may bring its own fields to allow users to customize the generation behaviour.
- Both
platforms
andpinnedPlatform
fields are optional, however when a custom binary is provided thepinnedPlatform
is required.
generator js {
provider = "photonjs"
}
generator js_custom_output {
provider = "photonjs"
output = "../src/generated/photon"
}
generator nexus_prisma {
provider = "nexus-prisma"
}
generator ts {
provider = "./path/to/custom/generator"
}
generator ts {
provider = "./path/to/custom/generator"
platforms = ["native", "linux-glibc-libssl1.0.2"]
pinnedPlatform = env("PLATFORM") // On local set to "native"; in production set to "linux-glibc-libssl1.0.2"
}
Note: The default
output
for thephotonjs
andnexus-prisma
providers 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
embed
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("POSTGRES_URL")
}
This feature is not implemented yet. As a workaround you can provide environment variables for both
url
andprovider
options.
datasource db {
provider = env("PRISMA_PROVIDER")
url = env("PRISMA_URL")
}
Sometimes it's helpful to target different environments based in the same schema file, for example:
datasource db {
enabled = env("SQLITE_URL")
provider = "sqlite"
url = env("SQLITE_URL")
}
datasource db {
enabled = env("POSTGRES_URL")
provider = "postgresql"
url = env("POSTGRES_URL")
}
model User {
id Int @id @db.int
first_name String @unique
}
Depending on which environment variable is set (in this case SQLITE_URL
or POSTGRES_URL
), the respective data source will be used. To set these variables you can either use a .env
-file(Coming soon) or export
the variables in your shell instance.
Tip: To quickly switch between environments you can source
a file with the export
commands.
// dev_env
export POSTGRES_URL=postgresql://test:test@localhost:5432/test?schema=public
$ source ./dev_env
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 configurability 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
}
Inline embeds add their own nested formatting rules:
model User {
id String
name String
customer embed {
id String
full_name String
cards embed {
type Card
}[]
}?
age Int
email String
}