NodeJS 使用Prisma2和Jest删除表中的所有项目

btxsgosb  于 2023-11-17  发布在  Node.js
关注(0)|答案(3)|浏览(162)

我想知道如何使用Prisma2和Jest删除表中的所有项目?
我读了CRUD documentation,我试着这样做:
user.test.js

....
import { PrismaClient } from "@prisma/client"

beforeEach(async () => {
    const prisma = new PrismaClient()
    await prisma.user.deleteMany({})
})
...

字符串
但我有一个错误:

Invalid `prisma.user.deleteMany()` invocation:
The change you are trying to make would violate the required relation 'PostToUser' between the `Post` and `User` models.


我的数据库

CREATE TABLE User (
  id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
  name VARCHAR(255),
  email VARCHAR(255) UNIQUE NOT NULL,
  password VARCHAR(255) NOT NULL
);

CREATE TABLE Post (
  id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
  title VARCHAR(255) NOT NULL,
  createdAt TIMESTAMP NOT NULL DEFAULT now(),
  content TEXT,
  published BOOLEAN NOT NULL DEFAULT false,
  fk_user_id INTEGER NOT NULL,
  CONSTRAINT `fk_user_id` FOREIGN KEY (fk_user_id) REFERENCES User(id) ON DELETE CASCADE
);


schema.prisma

model Post {
  content    String?
  createdAt  DateTime @default(now())
  fk_user_id Int
  id         Int      @default(autoincrement()) @id
  published  Boolean  @default(false)
  title      String
  author     User     @relation(fields: [fk_user_id], references: [id])

  @@index([fk_user_id], name: "fk_user_id")
}

model User {
  email    String   @unique
  id       Int      @default(autoincrement()) @id
  name     String?
  password String   @default("")
  Post     Post[]
  Profile  Profile?
}

sxissh06

sxissh061#

您违反了PostUser之间的外键约束。在删除Posts之前不能删除User

beforeEach(async () => {
    const prisma = new PrismaClient()
    await prisma.post.deleteMany({where: {...}}) //delete posts first
    await prisma.user.deleteMany({})
})

字符串
或者在外键上设置CASCADE删除,这样当你删除一个用户时,它的帖子会自动删除

bt1cpqcv

bt1cpqcv2#

这是另一种方法,这将删除所有行及其依赖行,也将重置id。这样你就可以遍历所有表,顺序无关紧要。

prisma.$executeRaw(`TRUNCATE TABLE ${table} RESTART IDENTITY CASCADE;`)

字符串

svujldwt

svujldwt3#

替代解决方案:
我从medium article中找到了一个指南,但这里是我使用的基于那篇文章的代码,唯一的区别是表名是动态的。
如果在表上正确设置了级联删除,它会很好地工作。
你也可以创建一个单独的函数truncateTable,并传递一个表名或prisma模型,或者也可以传递一个表名数组给refreshDatabase

import prisma from .....
import {Prisma} from ".prisma/client";

const tableNames = Object.values(Prisma.ModelName);

export default async function refreshDatabase() {
  for (const tableName of tableNames) {
    await prisma.$queryRawUnsafe(`Truncate ${tableName}`)
  }
}

字符串

相关问题