偏执
Sequelize 支持偏执表的概念。偏执表是这样一种表,当被告知删除一条记录时,它不会真正删除它。相反,名为 deletedAt
的特殊列将其值设置为该删除请求的时间戳。
¥Sequelize supports the concept of paranoid tables. A paranoid table is one that, when told to delete a record, it will not truly delete it. Instead, a special column called deletedAt
will have its value set to the timestamp of that deletion request.
这意味着偏执表执行记录的软删除,而不是硬删除。
¥This means that paranoid tables perform a soft-deletion of records, instead of a hard-deletion.
将模型定义为偏执
¥Defining a model as paranoid
要使模型偏执,你必须将 paranoid: true
选项传递给模型定义。Paranoid 需要时间戳才能工作(即,如果你也通过了 timestamps: false
,它将无法工作)。
¥To make a model paranoid, you must pass the paranoid: true
option to the model definition. Paranoid requires timestamps to work (i.e. it won't work if you also pass timestamps: false
).
你还可以将默认列名称(deletedAt
)更改为其他名称。
¥You can also change the default column name (which is deletedAt
) to something else.
class Post extends Model {}
Post.init(
{
/* attributes here */
},
{
sequelize,
paranoid: true,
// If you want to give a custom name to the deletedAt column
deletedAt: 'destroyTime',
},
);
删除
¥Deleting
当你调用 destroy
方法时,将发生软删除:
¥When you call the destroy
method, a soft-deletion will happen:
await Post.destroy({
where: {
id: 1,
},
});
// UPDATE "posts" SET "deletedAt"=[timestamp] WHERE "deletedAt" IS NULL AND "id" = 1
如果你确实想要硬删除并且你的模型是偏执的,你可以使用 force: true
选项强制它:
¥If you really want a hard-deletion and your model is paranoid, you can force it using the force: true
option:
await Post.destroy({
where: {
id: 1,
},
force: true,
});
// DELETE FROM "posts" WHERE "id" = 1
上面的示例使用静态 destroy
方法作为示例(Post.destroy
),但一切的工作方式与实例方法相同:
¥The above examples used the static destroy
method as an example (Post.destroy
), but everything works in the same way with the instance method:
const post = await Post.create({ title: 'test' });
console.log(post instanceof Post); // true
await post.destroy(); // Would just set the `deletedAt` flag
await post.destroy({ force: true }); // Would really delete the record
恢复
¥Restoring
要恢复软删除的记录,你可以使用 restore
方法,该方法既有静态版本又有实例版本:
¥To restore soft-deleted records, you can use the restore
method, which comes both in the static version as well as in the instance version:
// Example showing the instance `restore` method
// We create a post, soft-delete it and then restore it back
const post = await Post.create({ title: 'test' });
console.log(post instanceof Post); // true
await post.destroy();
console.log('soft-deleted!');
await post.restore();
console.log('restored!');
// Example showing the static `restore` method.
// Restoring every soft-deleted post with more than 100 likes
await Post.restore({
where: {
likes: {
[Op.gt]: 100,
},
},
});
其他查询的行为
¥Behavior with other queries
Sequelize 执行的每个查询都会自动忽略软删除记录(当然,原始查询除外)。
¥Every query performed by Sequelize will automatically ignore soft-deleted records (except raw queries, of course).
这意味着,例如,findAll
方法将不会看到软删除的记录,而只会获取未删除的记录。
¥This means that, for example, the findAll
method will not see the soft-deleted records, fetching only the ones that were not deleted.
即使你只是调用 findByPk
提供软删除记录的主键,结果也将是 null
,就好像该记录不存在一样。
¥Even if you simply call findByPk
providing the primary key of a soft-deleted record, the result will be null
as if that record didn't exist.
如果确实想让查询看到软删除的记录,可以将 paranoid: false
选项传递给查询方法。例如:
¥If you really want to let the query see the soft-deleted records, you can pass the paranoid: false
option to the query method. For example:
await Post.findByPk(123); // This will return `null` if the record of id 123 is soft-deleted
await Post.findByPk(123, { paranoid: false }); // This will retrieve the record
await Post.findAll({
where: { foo: 'bar' },
}); // This will not retrieve soft-deleted records
await Post.findAll({
where: { foo: 'bar' },
paranoid: false,
}); // This will also retrieve soft-deleted records