Introduction
Prisma is an open source, next-generation ORM that contains the following components.
- Prisma Client : auto-generated, type-safe query builder for Node.js and TypeScript
- Prisma Migrate : data migration system
- Prisma Studio : Graphical interface for querying and editing data in the database
The Prisma client can be used in any Node.js or TypeScript backend application (including Serverless applications and microservices). It can be a REST API, a GraphQL API, a gRPC API, or anything else that requires a database.
This article will give a quick overview of the basic usage of Prisma.
Official Quickstart example
Direct access to official example
Create a project template
Create a typescript project, using gts:
Install prisma dependencies:
|
|
Slightly adjust the contents of tsconfig.json as follows (the module used by gts is configured as commonjs, the main one needs to be adjusted):
|
|
Initialize prisma templates:
|
|
prisma cli has generated a schema template for us prisma/schema.prisma
:
and a dotenv
configuration file .env
:
|
|
Basic workflow
Adjust the database connection and just append the table structure definition on top of that. For example, we define a user
table:
model naming needs to meet the uppercase hump style and cannot use reserved words, refer to the official documentation prisma-schema-reference#naming-conventions
Run npx prisma migrate dev --name init
to create the database and generate the migration script:
Local rapid prototyping also allows you to use
db push
to modify the database directly without creating a migrate script, which is useful in scenarios where you are iterating locally and don’t care about the changes in between.However, in scenarios where the product environment expects to safely migrate the database without losing data,
migrate deploy
should be used instead ofdb push
. For a description ofdb push
and a comparison withmigrate
see the official documentation: db-push
Modify the schema to add a field:
Run npx prisma migrate dev --name add_foo_column
and the resulting sql is as follows:
Later, modify prisma/schema.prisma
and then run npx prisma migrate dev
again to synchronize the changes to the database. If you append the --create-only
parameter, only the migration.sql file will be generated and not synchronized to the database.
The migrate script (mainly the -migrate dev
and -migrate reset
commands require the shadow database) requires the createdb permission of the database, otherwise it will report an error. If your environment does not provide createdb permissions, you need to create a separate shadow database, specified by adding shadowDatabaseUrl = env('SHADOW_DATABASE_URL')
to the datasource db {}
configuration block, see the official documentation: shadow-database
The product environment runs the migrate script directly with migrate deploy
or migrate resolve
without creating a shadow database.
Schema Definition
Note that Prisma maintains a default set of schema to database type mappings, which can be changed by appending the @db.<database_type>
parameter if it does not meet your needs, e.g. the String
type maps to the TEXT
type of the database by default, and you may want to map to the VARCHAR
type:
prisma schema All supported field types and the database types that can be mapped ( @db.<database_type>
) can be found in the official documentation: model-field-scalar-types
Other common schema definitions
Annotations
prisma supports two types of comments //
and ///
, the former is just a normal comment on the code, the latter appears in the node syntax tree (AST) as Data Model Meta Format (DMMF):
|
|
Former prisma does not yet support database level table and field comments (DDL COMMENT), see the official issue
Currently you can only generate sql with
-create-only
parameter and change it by hand
Renaming tables/fields
To circumvent database case issues, the general database best practice is to name tables and fields consistently using lowercase underscores. For prisma, use the @@map
and @map
function definitions:
The corresponding generated sql is as follows:
For naming indexes, constraints, etc., refer to the official documentation: names-in-underlying-databas#using-custom-constraint-index-names
Field defaults ( @default
)
@default
can define the default value of a field, the parameters can be static fixed values like 5
, false
etc. or several functions provided by prisma like autoincrement()
, uuid()
, now()
etc. See the documentation: prisma-schema- reference#default
Enumeration types
Fields can be defined as enumerated types:
Corresponding to sql:
|
|
Automatically store the update time ( @updatedAt
)
This property automatically sets the update time:
Indexes ( @@index
)
Indexes can be created directly using the @@index
function:
If you want to customize the index type, you can use npx prisma migrate dev --create-only
to generate a migration.sql
file and then modify it in migration.sql
.
If you expect to define them in the schema file, you need to enable the extendedIndexes
preview feature:
You can use the type
parameter in @@index
to specify the index type:
For documentation on the @@index
section refer to: prisma-schema-reference#index
Documentation for the extendedIndexes
section: indexes
Field constraints
primary-key ( @id
/ @@id
)
Single primary key
Generate sql:
Union Primary Key
Generate sql:
uniqueness ( @unique
/ @@unique
)
Single column uniqueness
Multi-column uniqueness
Non-Null Constraints
The default field types are all non-null, and can be null by adding ?
and you’re done:
foreign key constraint ( @relation
)
is a little trickier, as you need to define the mutual correspondence between the two models as follows:
Generate sql:
|
|
There is a convenient way to quickly create such mappings, which is to use the prisma format
function directly.
For example, first create a table association like Hibernate:
Then execute npx prisma format
at the command line, or install the plugin Prisma in vscode and format it directly in vscode The above model mapping relationships are generated automatically.
For more definitions of mapping relations (one-to-one, one-to-many, many-to-many), please refer to the official documentation: relations
Using Prisma Client
After defining the schema and completing the migrate, you need to call the schema through prisma-client
to complete the database operations.
|
|
After installing @prisma/client
for the first time, prisma generate
will be called automatically to generate a customized client, later you need to call npx prisma generate
manually to generate a new client model after each schema change.
Just introduce the PrismaClient
component in your project:
To print sql you can configure it like this:
PrismaClient uses connection pooling by default. For the configuration of connection pooling, please refer to the official documentation: connection-pool
Basic CURD operations
For detailed basic CURD operations refer directly to the official documentation for a complete example: crud
It’s all relatively simple and easy to understand at a glance. The basic model-based CURD functions are mainly the following:
- findUnique
- findFirst
- findMany
- create
- update
- upsert
- delete
- createMany
- updateMany
- deleteMany
- count
- aggregate
- groupBy
In addition, you can control the fields returned via the select attribute:
See: select-fields for more details
Currently prisma does not support exclusion of specific fields (e.g. password), this design is being explored, see issue: prisma/prisma#5042
If you want to use correlation queries like join
, you can refer to the documentation: relation-queries
For JSONB
related queries, the prisma API also has support: working-with-json-fields fields/working-with-json-fields)
Transactional
Each basic CURD operation runs in a separate transaction (you can see the wrapper BEGIN....COMMIT
when printing the sql), and you can also explicitly use the $transaction
function to wrap multiple operations in a single transaction:
Calling sql
prisma provides some functions that contain the Raw
keyword and can be used directly with sql, such as :
All functions that call sql directly can be found in the official documentation: raw-database-access