Today, we are issuing the twenty-third Preview release: 2.0.0-preview023
(short: preview023
).
This release contains breaking changes, be sure to read the notes below before upgrading!
Breaking changes
Cursor-pagination API changed in Prisma Client
Because Prisma now supports composite unique constraints, the before
and after
API for cursor-pagination (which is based on unique fields) also changes. The cursor is now wrapped in an object which might have multiple fields.
Assume you have this Prisma model:
model Post {
id Int @default(autoincrement())
title String @unique
content String?
}
Before
const cursor = 42
const posts = await prisma.post.findMany({
after: cursor
})
After
const cursor = 42
const posts = await prisma.post.findMany({
after: { id: cursor }
})
Removed the enabled
property in datasource
blocks
The enabled
property was removed from the datasource
blocks.
Major improvements
In this issue, we're lifting a major limitation of Prisma which always required every model to have exactly one primary key constraint. In the Prisma schema, this primary key was represented using the @id
attribute.
With this release, you can now have tables:
- without primary keys (but unique constraints)
- with composite primary keys
- with composite unique constraints
Read below for more information on each of these new features. Lifting these limitations was a major effort, please be sure to report any bugs or other issues you encounter using these new features!
Allows models without IDs
In previous Prisma versions, there was a hard requirement that every model in your Prisma schema needed to have a single @id
field (which maps to a primary key constraint in the underlying database). This requirement is now lifted and your models don't need primary key constraints any more to be compatible with Prisma 2 (they do need at least one unique constraint though).
For example, this data model is now valid:
model Post {
title String @unique
content String?
published Boolean @default(false)
author User?
}
model User {
email String @unique
name String?
posts Post[]
}
Composite primary keys
As of this release, Prisma supports composite IDs (which map to multi-column primary key constraints in the underlying database). Composite IDs are defined on a "model-level" using the @@id
attribute. Here's an example:
model User {
firstName String
lastName String
email String
@@id([firstName, lastName])
}
This also impacts the Prisma Client API and how you're querying for single records, e.g. in findOne
, update
or delete
queries where you need to identify a record by its primary key (or another unique field). These queries take the following type as input:
export type UserWhereUniqueInput = {
firstName_lastName?: FirstNameLastNameCompoundUniqueInput | null
}
export type FirstNameLastNameCompoundUniqueInput = {
firstName: string
lastName: string
}
This means, in order to query for a User
record, you need to provide both firstName
and lastName
fields wrapped inside a firstName_lastName
object:
const user = await prisma.user.findOne({
where: {
firstName_lastName: {
firstName: "Jane",
lastName: "Doe"
}
}
})
Composite unique indexes / constraints
As of this release, Prisma also supports composite unique constraints (which map to multi-column unique constraints in the underlying database). Composite unique constraints are defined on a "model-level" using the @@unique
attribute.
Note: Primary key and unique constraints are very similar but have some differences on the database-level. You can learn more about the differences here.
Here's an example:
model User {
firstName String
lastName String
email String
@@unique([firstName, lastName])
}
This also impacts the Prisma Client API and how you're querying for single records, e.g. in findOne
, update
or delete
queries where you need to identify a record by its primary key (or another unique field). These queries take the following type as input:
export type UserWhereUniqueInput = {
firstName_lastName?: FirstNameLastNameCompoundUniqueInput | null
}
export type FirstNameLastNameCompoundUniqueInput = {
firstName: string
lastName: string
}
This means, in order to query for a User
record, you need to provide both firstName
and lastName
fields wrapped inside a firstName_lastName
object:
const user = await prisma.user.findOne({
where: {
firstName_lastName: {
firstName: "Jane",
lastName: "Doe"
}
}
})
Introspection now recognizes default constraints
Prisma's introspection now reconized DEFAULT
constraints that are defined on a column. These constraints are represented in the generated Prisma schema using the @default
attribute.
Optimize nested GraphQL queries that use Prisma Client ("dataloader")
When building a GraphQL server with Prisma Client, it wasn't easy to avoid the n+1 problem with nested queries. This release of Prisma Client optimizes the execution of GraphQL nested queries by batching requests against the database.
Fixes and improvements per Prisma 2 repository
prisma2
- Add @prisma/studio-types to prisma2 devDependencies
generate --watch
broken- Error: [/rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/macros/mod.rs:15:40] called
Option::unwrap()
on aNone
value - Add docs for
.raw
template literal API with parameters #1583 - Unclear rust error: called
Option::unwrap()
on aNone
value - [Introspection] Order of fields in @@index changes with alpha 808 for PostgreSQL
- add error formatting docs
- add docs for utility types
- remove mentions of mongodb
- Remove MongoDB from documentation
- Document SQLite connection strings
Error: P4001 The introspected database was empty: undefined
url or file if sqlite should be displayed instead of undefined- Clean up branches
- Document MySQL unix socket connection usage
- Error: Schema parsing thread 'main' panicked at 'assertion failed:
(left == right)
- [Introspection] "Error: Schema parsing thread 'main' panicked at 'Encountered impossible datamodel declaration during parsing: "
- [Introspection] Postgres serial type is missing @default(autoincrement())
- Document workarounds for No-identifier-tables
- Improve
.raw
template literal API with parameters - Document error formatting
- --experimental flag order
generate
shows "Downloading ..." every time when a custom binaryTarget is specified- [Introspection] Investigate field/model types
- Remove enabled field from datasource block
- Query Engine failed ENOENT
- Certificate identity files are required in both prisma folder and in the folder from which lift is executed
- Do not require environment variables for
generate
- Prisma is not including columns of Postgres type 'time without time zone' in schema
prisma-client-js
- Improve reserved words / denylist for code generation
- Implement new # private fields for PrismaClient
- Lowercasing of model and field names
.raw
template literal API with parametersJSON.parse(dmmfString)
fails on prisma schema with docs- Fix Error's meta property typing
- improve download logic
- Test Prisma Client with pgBouncer
- "Note, that by providing
native
, Prisma Client automatically resolvesrhel-openssl-1.0.x
" - Better runtime error handling for missing binaries
- Document utility types
- File name (
datamodel.mdl
) and client name (Photon JS
) in graphic in README need to be updated - Hide top-level client properties (as they are visible via JS code intellisense)
- tslint: Invalid 'await' of a non-Promise value
prisma-engines
- [Query Core] Housekeeping
- DMMF: add information about multi field uniques
- do not fail on missing env vars in dmmf
- Only build relevant binaries in connector-test-kit
- Return a known error on invalid/absent database string
- Fix crash on building of foreign keys overlapping with PK
- Panic for empty env var
- Implementing execute raw tests in rust
- Temporarily Drop Relations on Compound Ids
- Test explicit enum default migrations with @map
- Any Relation References
- Remove lazy-static
- Fix postgres field ordering inside indexes in sql schema describer
- Test index fields ordering is preserved in postgres sql-schema-describer
- Take
@map
into account when migrating enum values - Implement diffing of enum value directives
- Introspect Serial as Autoincrement on Postgres
- Optimize the amount of queries sent by sql-schema-describer on postgres
- Propagate quaint timeout messages to introspection connector errors
- Optimized Postgres Introspection
- Add rule for doc-comments to data model Parser
- Find one optimization
- Do not add @map to virtual back relation fields
- Remap Invalid Enum Values
- Single-field @@unique is not handled correctly.
- EPIC: @relation(references: ..) for multiple fields
- Query Engine: Loosen id requirement. At least one unique criteria is enough.
- EPIC: Loosen id requirement. At least one unique criteria is enough.