Schema incompatibilities
Overview
Each section on this page describes a potential problem when upgrading from Prisma 1 to Prisma ORM 2.x and later and explains the available workarounds.
Default values aren't represented in database
Problem
When adding the @default
directive in a Prisma 1 datamodel, the default values for this field are generated by the Prisma 1 server at runtime. There's no DEFAULT
constraint added to the database column. Because this constraint is not reflected in the database itself, the Prisma ORM 2.x and later versions of introspection can't recognize it.
Example
Prisma 1 datamodel
type Post {
id: ID! @id
published: Boolean @default(value: false)
}
Prisma 1 generated SQL migration
CREATE TABLE "Post" (
id VARCHAR(25) PRIMARY KEY NOT NULL,
published BOOLEAN NOT NULL
);
Result of introspection in Prisma ORM versions 2.x and later
model Post {
id String @id
published Boolean
}
Because the DEFAULT
constraint has not been added to the database when mapping the Prisma 1 datamodel to the database with prisma deploy
, Prisma ORM v2 (and later versions) doesn't recognize it during introspection.
Workarounds
Manually add a DEFAULT
constraint to the database column
You can alter the column to add the DEFAULT
constraint as follows:
ALTER TABLE "Post"
ALTER COLUMN published SET DEFAULT false;
After this adjustment, you can re-introspect your database and the @default
attribute will be added to the published
field:
model Post {
id String @id
published Boolean @default(false)
}
Manually add a @default
attribute to the Prisma model
You can add the @default
attribute to the Prisma model:
model Post {
id String
published Boolean @default(false)
}
If the @default
attribute is set in the Prisma schema and you run prisma generate
, the resulting Prisma Client code will generate the specified default values at runtime (similar to what the Prisma 1 server did in Prisma 1).
Generated CUIDs as ID values aren't represented in database
Problem
Prisma 1 auto-generates ID values as CUIDs for ID
fields when they're annotated with the @id
directive. These CUIDs are generated by the Prisma 1 server at runtime. Because this behavior is not reflected in the database itself, the introspection in Prisma ORM 2.x and later can't recognize it.
Example
Prisma 1 datamodel
type Post {
id: ID! @id
}
Prisma 1 generated SQL migration
CREATE TABLE "Post" (
id VARCHAR(25) PRIMARY KEY NOT NULL
);
Result of introspection in Prisma ORM versions 2.x and later
model Post {
id String @id
}
Because there's no indication of the CUID behavior in the database, Prisma ORM's introspection doesn't recognize it.
Workaround
As a workaround, you can manually add the @default(cuid())
attribute to the Prisma model:
model Post {
id String @id @default(cuid())
}
If the @default
attribute is set in the Prisma schema and you run prisma generate
, the resulting Prisma Client code will generate the specified default values at runtime (similar to what the Prisma 1 server did in Prisma 1).
Note that you'll have to re-add the attribute after each introspection because introspection removes it (as the previous version of the Prisma schema is overwritten)!
@createdAt
isn't represented in database
Problem
Prisma 1 auto-generates values for DateTime
fields when they're annotated with the @createdAt
directive. These values are generated by the Prisma 1 server at runtime. Because this behavior is not reflected in the database itself, the introspection in Prisma ORM 2.x and later can't recognize it.
Example
Prisma 1 datamodel
type Post {
id: ID! @id
createdAt: DateTime! @createdAt
}
Prisma 1 generated SQL migration
CREATE TABLE "Post" (
id VARCHAR(25) PRIMARY KEY NOT NULL,
"createdAt" TIMESTAMP NOT NULL
);
Result of introspection in Prisma ORM 2.x and later versions
model Post {
id String @id
createdAt DateTime
}
Workarounds
Manually add DEFAULT CURRENT_TIMESTAMP
to the database column
You can alter the column to add the DEFAULT
constraint as follows:
ALTER TABLE "Post"
ALTER COLUMN "createdAt" SET DEFAULT CURRENT_TIMESTAMP;
After this adjustment, you can re-introspect your database and the @default
attribute will be added to the createdAt
field:
model Post {
id String
createdAt DateTime @default(now())
}
Manually add the @default(now())
attribute to the Prisma model
As a workaround, you can manually add the @default(now())
attribute to the Prisma model:
model Post {
id String @id
createdAt DateTime @default(now())
}
If the @default
attribute is set in the Prisma schema and you run prisma generate
, the resulting Prisma Client code will generate the specified default values at runtime (similar to what the Prisma 1 server did in Prisma 1).
Note that you'll have to re-add the attribute after each introspection because introspection removes it (as the previous version of the Prisma schema is overwritten)!
@updatedAt
isn't represented in database
Problem
Prisma 1 auto-generates values for DateTime
fields when they're annotated with the @updatedAt
directive. These values are generated by the Prisma 1 server at runtime. Because this behavior is not reflected in the database itself, the introspection in Prisma ORM 2.x and later can't recognize it..
Example
Prisma 1 datamodel
type Post {
id: ID! @id
updatedAt: DateTime! @updatedAt
}
Prisma 1 generated SQL migration
CREATE TABLE "Post" (
id VARCHAR(25) PRIMARY KEY NOT NULL,
updatedAt TIMESTAMP
);
Result of introspection in Prisma ORM 2.x and later versions
model Post {
id String @id
updatedAt DateTime
}
Workarounds
Manually add the @updatedAt
attribute to the Prisma model
As a workaround, you can manually add the @updatedAt
attribute to the Prisma model:
model Post {
id String @id
updatedAt DateTime @updatedAt
}
If the @updatedAt
attribute is set in the Prisma schema and you run prisma generate
, the resulting Prisma Client code will automatically generate values for this column when an existing record is updated (similar to what the Prisma 1 server did in Prisma 1).
Note that you'll have to re-add the attribute after each introspection because introspection removes it (as the previous version of the Prisma schema is overwritten)!
Inline 1-1 relations are recognized as 1-n (missing UNIQUE
constraint)
Problem
In the datamodel v1.1 that was introduced in Prisma ORM v1.31, 1-1 relations can be declared as inline. In that case, the relation will not be maintained via a relation table but via a single foreign key on one of the two tables involved.
When this approach is used, Prisma ORM doesn't add a UNIQUE
constraint to the foreign key column which means that after introspection in Prisma ORM version 2.x and later, this former 1-1 relation will be added as a 1-n relation to the Prisma schema.
Example
Prisma ORM datamodel v1.1 (available from Prisma ORM v1.31)
type User {
id: ID! @id
profile: Profile @relation(link: INLINE)
}
type Profile {
id: ID! @id
user: User
}
Note that omitting the @relation
directive in this case would result in the same behavior because link: INLINE
is the default for 1-1 relations.
Prisma 1 generated SQL migration
CREATE TABLE "User" (
id VARCHAR(25) PRIMARY KEY NOT NULL
);
CREATE TABLE "Profile" (
id VARCHAR(25) PRIMARY KEY NOT NULL,
"user" VARCHAR(25),
FOREIGN KEY ("user") REFERENCES "User"(id)
);
Result of introspection in Prisma ORM 2.x and later versions
model User {
id String @id
Profile Profile[]
}
model Profile {
id String @id
user String?
User User? @relation(fields: [user], references: [id])
}
Because there's no UNIQUE
constraint defined on the user
column (which represents the foreign key in this relation), Prisma ORM's introspection recognizes the relation as 1-n.
Workaround
Manually add UNIQUE
constraint to the foreign key column
You can alter the foreign key column to add the UNIQUE
constraint as follows:
ALTER TABLE "Profile"
ADD CONSTRAINT userId_unique UNIQUE ("user");
After this adjustment, you can re-introspect your database and the 1-1 relation will be properly recognized:
model User {
id String @id
Profile Profile?
}
model Profile {
id String @id
user String? @unique
User User? @relation(fields: [user], references: [id])
}