Skip to main content

参考行动

引用操作决定当你的应用删除或更新相关记录时记录会发生什么情况。

¥Referential actions determine what happens to a record when your application deletes or updates a related record.

从版本 2.26.0 开始,你可以在 Prisma 架构中的关系字段上定义引用操作。这允许你在 Prisma ORM 级别定义引用操作,例如级联删除和级联更新。

¥From version 2.26.0, you can define referential actions on the relation fields in your Prisma schema. This allows you to define referential actions like cascading deletes and cascading updates at a Prisma ORM level.

info

版本差异

¥Version differences

  • 如果你使用版本 3.0.1 或更高版本,则可以使用本页所述的引用操作。

    ¥If you use version 3.0.1 or later, you can use referential actions as described on this page.

  • 如果你使用 2.26.0 和 3.0.0 之间的版本,则可以按照本页所述使用引用操作,但必须 启用预览功能标志 referentialActions

    ¥If you use a version between 2.26.0 and 3.0.0, you can use referential actions as described on this page, but you must enable the preview feature flag referentialActions.

  • 如果你使用版本 2.25.0 或更早版本,你可以在数据库中手动配置级联删除。

    ¥If you use version 2.25.0 or earlier, you can configure cascading deletes manually in your database.

在以下示例中,将 onDelete: Cascade 添加到 Post 模型上的 author 字段意味着删除 User 记录也将删除所有相关的 Post 记录。

¥In the following example, adding onDelete: Cascade to the author field on the Post model means that deleting the User record will also delete all related Post records.

schema.prisma
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
authorId Int
}

model User {
id Int @id @default(autoincrement())
posts Post[]
}

如果你不指定参考操作,则 Prisma ORM 使用默认值

¥If you do not specify a referential action, Prisma ORM uses a default.

danger

如果你从 2.26.0 之前的版本升级:检查 参考操作的升级路径 部分非常重要。Prisma ORM 对引用操作的支持消除了 Prisma Client 中防止运行时级联删除的安全网。如果你在不升级数据库的情况下使用该功能,旧的默认操作 - ON DELETE CASCADE - 变得活跃。这可能会导致你意想不到的级联删除。

¥If you upgrade from a version earlier than 2.26.0: It is extremely important that you check the upgrade paths for referential actions section. Prisma ORM's support of referential actions removes the safety net in Prisma Client that prevents cascading deletes at runtime. If you use the feature without upgrading your database, the old default action - ON DELETE CASCADE - becomes active. This might result in cascading deletes that you did not expect.

什么是参考行动?

¥What are referential actions?

引用操作是定义当你运行 updatedelete 查询时数据库如何处理引用记录的策略。

¥Referential actions are policies that define how a referenced record is handled by the database when you run an update or delete query.

Referential actions on the database level

引用操作是外键约束的功能,用于保留数据库中的引用完整性。

¥Referential actions are features of foreign key constraints that exist to preserve referential integrity in your database.

当你在 Prisma 架构中定义数据模型之间的关系时,你使用数据库中不存在的 关系字段 和数据库中存在的 标量场。这些外键在数据库级别连接模型。

¥When you define relationships between data models in your Prisma schema, you use relation fields, which do not exist on the database, and scalar fields, which do exist on the database. These foreign keys connect the models on the database level.

参照完整性规定这些外键必须引用相关数据库表中现有的主键值。在 Prisma 架构中,这通常由相关模型上的 id 字段表示。

¥Referential integrity states that these foreign keys must reference an existing primary key value in the related database table. In your Prisma schema, this is generally represented by the id field on the related model.

默认情况下,数据库将拒绝任何违反引用完整性的操作,例如删除引用的记录。

¥By default a database will reject any operation that violates the referential integrity, for example, by deleting referenced records.

如何使用参考动作

¥How to use referential actions

引用操作在 @relation 属性中定义,并映射到基础数据库中外键约束的操作。如果不指定参考操作,则 Prisma ORM 恢复为默认值

¥Referential actions are defined in the @relation attribute and map to the actions on the foreign key constraint in the underlying database. If you do not specify a referential action, Prisma ORM falls back to a default.

以下模型定义了 UserPost 之间的一对多关系以及 PostTag 之间的多对多关系,并具有显式定义的引用操作:

¥The following model defines a one-to-many relation between User and Post and a many-to-many relation between Post and Tag, with explicitly defined referential actions:

schema.prisma
model User {
id Int @id @default(autoincrement())
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
title String
tags TagOnPosts[]
User User? @relation(fields: [userId], references: [id], onDelete: SetNull, onUpdate: Cascade)
userId Int?
}

model TagOnPosts {
id Int @id @default(autoincrement())
post Post? @relation(fields: [postId], references: [id], onUpdate: Cascade, onDelete: Cascade)
tag Tag? @relation(fields: [tagId], references: [id], onUpdate: Cascade, onDelete: Cascade)
postId Int?
tagId Int?
}

model Tag {
id Int @id @default(autoincrement())
name String @unique
posts TagOnPosts[]
}

该模型明确定义了以下参考操作:

¥This model explicitly defines the following referential actions:

  • 如果删除 Tag,则也会使用 Cascade 引用操作删除 TagOnPosts 中的相应标签分配

    ¥If you delete a Tag, the corresponding tag assignment is also deleted in TagOnPosts, using the Cascade referential action

  • 如果你删除 User,则由于 SetNull 引用操作,通过将字段值设置为 Null,作者将从所有帖子中删除。为此,UseruserId 必须是 Post 中的可选字段。

    ¥If you delete a User, the author is removed from all posts by setting the field value to Null, because of the SetNull referential action. To allow this, User and userId must be optional fields in Post.

Prisma ORM 支持以下引用操作:

¥Prisma ORM supports the following referential actions:

参考操作默认值

¥Referential action defaults

如果你不指定引用操作,Prisma ORM 将使用以下默认值:

¥If you do not specify a referential action, Prisma ORM uses the following defaults:

条款可选关系强制关系
onDeleteSetNullRestrict
onUpdateCascadeCascade

例如,在以下架构中,所有 Post 记录必须通过 author 关系连接到 User

¥For example, in the following schema all Post records must be connected to a User via the author relation:

model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
}

model User {
id Int @id @default(autoincrement())
posts Post[]
}

该架构未在强制 author 关系字段上显式定义引用操作,这意味着适用 RestrictonDeleteCascadeonUpdate 的默认引用操作。

¥The schema does not explicitly define referential actions on the mandatory author relation field, which means that the default referential actions of Restrict for onDelete and Cascade for onUpdate apply.

注意事项

¥Caveats

以下注意事项适用:

¥The following caveats apply:

  • 隐式多对多关系 不支持引用操作。要使用引用操作,你必须定义显式的多对多关系并在 连接表 上定义引用操作。

    ¥Referential actions are not supported on implicit many-to-many relations. To use referential actions, you must define an explicit many-to-many relation and define your referential actions on the join table.

  • 参考操作和必需/可选关系的某些组合是不兼容的。例如,在删除引用记录时,在所需关系上使用 SetNull 将导致数据库错误,因为会违反不可空约束。请参阅 这个 GitHub 问题 了解更多信息。

    ¥Certain combinations of referential actions and required/optional relations are incompatible. For example, using SetNull on a required relation will lead to database errors when deleting referenced records because the non-nullable constraint would be violated. See this GitHub issue for more information.

参考动作的类型

¥Types of referential actions

下表显示了每个数据库支持的引用操作。

¥The following table shows which referential action each database supports.

数据库级联限制无动作置空默认设置
PostgreSQL✔️✔️✔️✔️✔️
MySQL/MariaDB✔️✔️✔️✔️❌ (✔️†)
SQLite✔️✔️✔️✔️✔️
SQL Server✔️✔️✔️✔️
CockroachDB✔️✔️✔️✔️✔️
MongoDB††✔️✔️✔️✔️

参考操作的特殊情况

¥Special cases for referential actions

引用操作是 ANSI SQL 标准的一部分。但是,在某些特殊情况下,某些关系数据库与标准存在偏差。

¥Referential actions are part of the ANSI SQL standard. However, there are special cases where some relational databases diverge from the standard.

MySQL/MariaDB

MySQL/MariaDB 以及底层的 InnoDB 存储引擎不支持 SetDefault。确切的行为取决于数据库版本:

¥MySQL/MariaDB, and the underlying InnoDB storage engine, does not support SetDefault. The exact behavior depends on the database version:

  • 在 MySQL 版本 8 及更高版本以及 MariaDB 版本 10.5 及更高版本中,SetDefault 实际上充当 NoAction 的别名。你可以使用 SET DEFAULT 引用操作定义表,但在运行时会触发外键约束错误。

    ¥In MySQL versions 8 and later, and MariaDB versions 10.5 and later, SetDefault effectively acts as an alias for NoAction. You can define tables using the SET DEFAULT referential action, but a foreign key constraint error is triggered at runtime.

  • 在 MySQL 版本 5.6 及更高版本以及 MariaDB 版本 10.5 之前,尝试使用 SET DEFAULT 引用操作创建表定义会失败并出现语法错误。

    ¥In MySQL versions 5.6 and later, and MariaDB versions before 10.5, attempting to create a table definition with the SET DEFAULT referential action fails with a syntax error.

因此,当你将 mysql 设置为数据库提供程序时,Prisma ORM 会警告用户将 Prisma 架构中的 SetDefault 引用操作替换为其他操作。

¥For this reason, when you set mysql as the database provider, Prisma ORM warns users to replace SetDefault referential actions in the Prisma schema with another action.

PostgreSQL

PostgreSQL 是 Prisma ORM 支持的唯一数据库,它允许你定义引用不可为空字段的 SetNull 引用操作。但是,当在运行时触发操作时,这会引发外键约束错误。

¥PostgreSQL is the only database supported by Prisma ORM that allows you to define a SetNull referential action that refers to a non-nullable field. However, this raises a foreign key constraint error when the action is triggered at runtime.

因此,当你在(默认)foreignKeys 关系模式下将 postgres 设置为数据库提供程序时,Prisma ORM 会警告用户将包含在具有 SetNull 引用操作的 @relation 属性中的任何字段标记为可选。对于所有其他数据库提供程序,Prisma ORM 会拒绝带有验证错误的架构。

¥For this reason, when you set postgres as the database provider in the (default) foreignKeys relation mode, Prisma ORM warns users to mark as optional any fields that are included in a @relation attribute with a SetNull referential action. For all other database providers, Prisma ORM rejects the schema with a validation error.

SQL Server

Restrict 不适用于 SQL Server 数据库,但你可以使用 NoAction

¥Restrict is not available for SQL Server databases, but you can use NoAction instead.

Cascade

  • onDelete: Cascade 删除引用记录将触发引用记录的删除。

    ¥onDelete: Cascade Deleting a referenced record will trigger the deletion of referencing record.

  • onUpdate: Cascade 如果更新了从属记录的引用标量字段,则更新关系标量字段。

    ¥onUpdate: Cascade Updates the relation scalar fields if the referenced scalar fields of the dependent record are updated.

用法示例

¥Example usage

schema.prisma
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade, onUpdate: Cascade)
authorId Int
}

model User {
id Int @id @default(autoincrement())
posts Post[]
}
使用 Cascade 的结果

¥Result of using Cascade

如果删除 User 记录,那么他们的帖子也会被删除。如果用户的 id 更新了,那么对应的 authorId 也会更新。

¥If a User record is deleted, then their posts are deleted too. If the user's id is updated, then the corresponding authorId is also updated.

如何使用级联删除

¥How to use cascading deletes

Restrict

  • onDelete: Restrict 如果存在任何引用记录,则防止删除。

    ¥onDelete: Restrict Prevents the deletion if any referencing records exist.

  • onUpdate: Restrict 防止引用记录的标识符被更改。

    ¥onUpdate: Restrict Prevents the identifier of a referenced record from being changed.

用法示例

¥Example usage

schema.prisma
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id], onDelete: Restrict, onUpdate: Restrict)
authorId Int
}

model User {
id Int @id @default(autoincrement())
posts Post[]
}
使用 Restrict 的结果

¥Result of using Restrict

User 的帖子无法删除。Userid 无法更改。

¥Users with posts cannot be deleted. The User's id cannot be changed.

warning

Restrict 操作在 微软 SQL 服务器 上不可用,并会触发架构验证错误。相反,你可以使用 NoAction,它会产生相同的结果并且与 SQL Server 兼容。

¥The Restrict action is not available on Microsoft SQL Server and triggers a schema validation error. Instead, you can use NoAction, which produces the same result and is compatible with SQL Server.

NoAction

NoAction 操作与 Restrict 类似,两者之间的差异取决于所使用的数据库:

¥The NoAction action is similar to Restrict, the difference between the two is dependent on the database being used:

  • PostgreSQL:NoAction 允许将检查(如果表上存在引用的行)推迟到事务稍后进行。请参阅 PostgreSQL 文档 了解更多信息。

    ¥PostgreSQL: NoAction allows the check (if a referenced row on the table exists) to be deferred until later in the transaction. See the PostgreSQL docs for more information.

  • MySQL:NoAction 的行为与 Restrict 完全相同。请参阅 MySQL 文档 了解更多信息。

    ¥MySQL: NoAction behaves exactly the same as Restrict. See the MySQL docs for more information.

  • SQLite:当相关主键被修改或删除时,不会执行任何操作。请参阅 SQLite 文档 了解更多信息。

    ¥SQLite: When a related primary key is modified or deleted, no action is taken. See the SQLite docs for more information.

  • SQL 服务器:当删除或修改引用的记录时,会引发错误。请参阅 SQL Server 文档 了解更多信息。

    ¥SQL Server: When a referenced record is deleted or modified, an error is raised. See the SQL Server docs for more information.

  • MongoDB(从版本 3.6.0 开始预览):修改或删除记录时,不会对任何相关记录执行任何操作。

    ¥MongoDB (in preview from version 3.6.0): When a record is modified or deleted, nothing is done to any related records.

warning

如果你是 在 Prisma 客户端中管理关系 而不是在数据库中使用外键,你应该意识到目前 Prisma ORM 仅实现引用操作。外键也会创建约束,这使得不可能以违反这些约束的方式操作数据:数据库不执行查询,而是返回错误。如果你在 Prisma 客户端中模拟参照完整性,则不会创建这些约束,因此,如果你将参照操作设置为 NoAction,则不会进行检查来阻止你破坏参照完整性。

¥If you are managing relations in Prisma Client rather than using foreign keys in the database, you should be aware that currently Prisma ORM only implements the referential actions. Foreign keys also create constraints, which make it impossible to manipulate data in a way that would violate these constraints: instead of executing the query, the database responds with an error. These constraints will not be created if you emulate referential integrity in Prisma Client, so if you set the referential action to NoAction there will be no checks to prevent you from breaking the referential integrity.

用法示例

¥Example usage

schema.prisma
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction)
authorId Int
}

model User {
id Int @id @default(autoincrement())
posts Post[]
}
使用 NoAction 的结果

¥Result of using NoAction

User 的帖子无法删除。Userid 无法更改。

¥User's with posts cannot be deleted. The User's id cannot be changed.

SetNull

  • onDelete: SetNull 引用对象的标量字段将设置为 NULL

    ¥onDelete: SetNull The scalar field of the referencing object will be set to NULL.

  • onUpdate: SetNull 当更新引用对象的标识符时,引用对象的标量字段将设置为 NULL

    ¥onUpdate: SetNull When updating the identifier of a referenced object, the scalar fields of the referencing objects will be set to NULL.

SetNull 仅适用于可选关系。对于所需的关系,由于标量字段不能为空,因此将引发运行时错误。

¥SetNull will only work on optional relations. On required relations, a runtime error will be thrown since the scalar fields cannot be null.

schema.prisma
model Post {
id Int @id @default(autoincrement())
title String
author User? @relation(fields: [authorId], references: [id], onDelete: SetNull, onUpdate: SetNull)
authorId Int?
}

model User {
id Int @id @default(autoincrement())
posts Post[]
}
使用 SetNull 的结果

¥Result of using SetNull

删除 User 时,其所有撰写的帖子的 authorId 将被设置为 NULL

¥When deleting a User, the authorId will be set to NULL for all its authored posts.

更改 Userid 时,其所有撰写的帖子的 authorId 将设置为 NULL

¥When changing a User's id, the authorId will be set to NULL for all its authored posts.

SetDefault

  • onDelete: SetDefault 引用对象的标量字段将设置为字段默认值。

    ¥onDelete: SetDefault The scalar field of the referencing object will be set to the fields default value.

  • onUpdate: SetDefault 引用对象的标量字段将设置为字段默认值。

    ¥onUpdate: SetDefault The scalar field of the referencing object will be set to the fields default value.

这些需要使用 @default 设置关系标量字段的默认值。如果没有为任何标量字段提供默认值,则会引发运行时错误。

¥These require setting a default for the relation scalar field with @default. If no defaults are provided for any of the scalar fields, a runtime error will be thrown.

schema.prisma
model Post {
id Int @id @default(autoincrement())
title String
authorUsername String? @default("anonymous")
author User? @relation(fields: [authorUsername], references: [username], onDelete: SetDefault, onUpdate: SetDefault)
}

model User {
username String @id
posts Post[]
}
使用 SetDefault 的结果

¥Result of using SetDefault

删除 User 时,其现有帖子的 authorUsername 字段值将设置为“匿名”。

¥When deleting a User, its existing posts' authorUsername field values will be set to 'anonymous'.

Userusername 更改时,其现有帖子的 authorUsername 字段值将设置为“匿名”。

¥When the username of a User changes, its existing posts' authorUsername field values will be set to 'anonymous'.

数据库特定要求

¥Database-specific requirements

如果你的数据模型中有 自我关系循环关系,MongoDB 和 SQL Server 对引用操作有特定要求。如果你与 多级联路径 有关系,SQL Server 也有特定要求。

¥MongoDB and SQL Server have specific requirements for referential actions if you have self-relations or cyclic relations in your data model. SQL Server also has specific requirements if you have relations with multiple cascade paths.

2.25.0 及更早版本的升级路径

¥Upgrade paths from versions 2.25.0 and earlier

升级时你可以采取多种路径,根据所需的结果,它们会产生不同的结果。

¥There are a couple of paths you can take when upgrading which will give different results depending on the desired outcome.

如果你当前使用迁移工作流程,则可以运行内省来检查默认值如何反映在你的架构中。如果需要,你可以手动更新数据库。

¥If you currently use the migration workflow, you can run an introspection to check how the defaults are reflected in your schema. You can then manually update your database if you need to.

你还可以决定跳过检查默认值并运行迁移以使用 新的默认值 更新数据库。

¥You can also decide to skip checking the defaults and run a migration to update your database with the new default values.

以下假设你已升级到 2.26.0 或更高版本并启用预览功能标志,或者升级到 3.0.0 或更高版本:

¥The following assumes you have upgraded to 2.26.0 or newer and enabled the preview feature flag, or upgraded to 3.0.0 or newer:

使用内省

¥Using Introspection

如果你对数据库进行 内省,则在数据库级别配置的引用操作将反映在你的 Prisma 架构中。如果你一直在使用 Prisma Migrate 或 prisma db push 来管理数据库架构,这些可能是 2.25.0 及更早版本的 默认值

¥If you Introspect your database, the referential actions configured at the database level will be reflected in your Prisma Schema. If you have been using Prisma Migrate or prisma db push to manage the database schema, these are likely to be the default values from 2.25.0 and earlier.

当你运行 Introspection 时,Prisma ORM 会将数据库中的所有外键与 schema 进行比较,如果 SQL 语句 ON DELETEON UPDATE 与默认值不匹配,它们将在 schema 文件中显式设置。

¥When you run an Introspection, Prisma ORM compares all the foreign keys in the database with the schema, if the SQL statements ON DELETE and ON UPDATE do not match the default values, they will be explicitly set in the schema file.

内省后,你可以查看架构中的非默认子句。要查看的最重要的子句是 onDelete,它在 2.25.0 及更早版本中默认为 Cascade

¥After introspecting, you can review the non-default clauses in your schema. The most important clause to review is onDelete, which defaults to Cascade in 2.25.0 and earlier.

warning

如果你使用 delete()deleteMany() 方法,现在将执行 级联删除,因为 referentialActions 预览功能删除了 Prisma Client 中先前阻止运行时级联删除的安全网。请务必检查你的代码并进行相应的调整。

¥If you are using either the delete() or deleteMany() methods, cascading deletes will now be performed as the referentialActions preview feature removed the safety net in Prisma Client that previously prevented cascading deletes at runtime. Be sure to check your code and make any adjustments accordingly.

确保你对架构中 onDelete: Cascade 的每种情况都感到满意。如果没有,则:

¥Make sure you are happy with every case of onDelete: Cascade in your schema. If not, either:

  • 修改你的 Prisma 架构和 db pushdev migrate 以更改数据库

    ¥Modify your Prisma schema and db push or dev migrate to change the database

or

  • 如果你使用仅内省工作流程,请手动更新底层数据库

    ¥Manually update the underlying database if you use an introspection-only workflow

以下示例将导致级联删除,如果删除 User,则所有 Post 也将被删除。

¥The following example would result in a cascading delete, if the User is deleted then all of their Post's will be deleted too.

博客架构示例

¥A blog schema example

model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
authorId Int
}

model User {
id Int @id @default(autoincrement())
posts Post[]
}

使用迁移

¥Using Migration

运行 迁移(或 prisma db push 命令)时,新的默认值 将应用于你的数据库。

¥When running a Migration (or the prisma db push command) the new defaults will be applied to your database.

info

与你第一次运行 Introspect 时不同,新的引用操作子句和属性不会通过 Prisma VSCode 扩展自动添加到你的 prisma 架构中。如果你希望使用新默认值以外的任何内容,则必须手动添加它们。

¥Unlike when you run an Introspect for the first time, the new referential actions clause and property, will not automatically be added to your prisma schema by the Prisma VSCode extension. You will have to manually add them if you wish to use anything other than the new defaults.

在 Prisma 架构中显式定义引用操作是可选的。如果你没有显式定义关系的引用操作,Prisma ORM 将使用 新的默认值

¥Explicitly defining referential actions in your Prisma schema is optional. If you do not explicitly define a referential action for a relation, Prisma ORM uses the new defaults.

请注意,可以根据具体情况添加参考操作。这意味着你可以将它们添加到一个关系中,并通过不手动指定任何内容来将其余设置保留为默认值。

¥Note that referential actions can be added on a case by case basis. This means that you can add them to one single relation and leave the rest set to the defaults by not manually specifying anything.

检查错误

¥Checking for errors

在升级到 2.26.0 并启用引用操作预览功能之前,Prisma ORM 阻止删除记录,同时使用 delete()deleteMany() 来保持引用完整性。Prisma 客户端将抛出自定义运行时错误,错误代码为 P2014

¥Before upgrading to 2.26.0 and enabling the referential actions preview feature, Prisma ORM prevented the deletion of records while using delete() or deleteMany() to preserve referential integrity. A custom runtime error would be thrown by Prisma Client with the error code P2014.

升级并启用引用操作预览功能后,Prisma ORM 不再执行运行时检查。你可以改为指定自定义引用操作来保留关系之间的引用完整性。

¥After upgrading and enabling the referential actions preview feature, Prisma ORM no longer performs runtime checks. You can instead specify a custom referential action to preserve the referential integrity between relations.

当你使用 NoActionRestrict 来防止删除记录时,2.26.0 后的错误消息将与 2.26.0 之前的错误消息不同。这是因为它们现在由数据库而不是 Prisma 客户端触发。预计新的错误代码是 P2003

¥When you use NoAction or Restrict to prevent the deletion of records, the error messages will be different post 2.26.0 compared to pre 2.26.0. This is because they are now triggered by the database and not Prisma Client. The new error code that can be expected is P2003.

为了确保捕获这些新错误,你可以相应地调整代码。

¥To make sure you catch these new errors you can adjust your code accordingly.

捕获错误的示例

¥Example of catching errors

以下示例使用以下博客架构,PostUser 之间具有一对多关系,并在 author 字段上设置 Restrict 引用操作。

¥The following example uses the below blog schema with a one-to-many relationship between Post and User and sets a Restrict referential actions on the author field.

这意味着如果用户有帖子,则无法删除该用户(及其帖子)。

¥This means that if a user has a post, that user (and their posts) cannot be deleted.

schema.prisma
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id], onDelete: Restrict)
authorId String
}

model User {
id Int @id @default(autoincrement())
posts Post[]
}

在升级并启用引用操作预览功能之前,尝试删除有帖子的用户时你会收到的错误代码为 P2014 及其消息:

¥Prior to upgrading and enabling the referential actions preview feature, the error code you would receive when trying to delete a user which has posts would be P2014 and it's message:

"你尝试进行的更改将违反 {model_a_name} 和 {model_b_name---BRACE- 之间所需的关系 '---左括号---relation_name}' 右---模型。"

¥"The change you are trying to make would violate the required relation '{relation_name}' between the {model_a_name} and {model_b_name} models."

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
try {
await prisma.user.delete({
where: {
id: 'some-long-id',
},
})
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
if (error.code === 'P2014') {
console.log(error.message)
}
}
}
}

main()

为了确保检查代码中的错误是否正确,请修改检查以查找 P2003,这将传递消息:

¥To make sure you are checking for the correct errors in your code, modify your check to look for P2003, which will deliver the message:

“该字段的外键约束失败:{field_name}"

¥"Foreign key constraint failed on the field: {field_name}"

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
try {
await prisma.user.delete({
where: {
id: 'some-long-id'
}
})
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
if (error.code === 'P2014') {
if (error.code === 'P2003') {
console.log(error.message)
}
}
}
}

main()