如何在 prisma 中使用带有外键的 createMany?

Posted

技术标签:

【中文标题】如何在 prisma 中使用带有外键的 createMany?【英文标题】:How can I use createMany with foreign keys in prisma? 【发布时间】:2021-08-31 16:02:09 【问题描述】:

我是使用 Prisma 的初学者,我一直在试图弄清楚如何最初将数据加载到 postgres 表中。我已经尝试按照 prisma 中的这个示例播种我的数据库 https://github.com/prisma/prisma-examples/tree/latest/javascript/graphql-auth 但似乎 main() 没有被命令“npx prisma db seed --preview-feature”触发。 所以我尝试通过一个临时函数插入我的数据库,但在启动开发服务器时出现无效调用错误:

Foreign key constraint failed on the field: Animals_categoryName_fkey (index)

但是当我不使用外键时,我没有收到此错误。下面是我的 schema.prisma、类型和我需要添加的数据。

Schema.prisma

datasource db 
  provider = "postgresql"
  url      = env("DATABASE_URL")


generator client 
  provider = "prisma-client-js"


model Animals
  id Int @id @default(autoincrement())
  image String
  price String
  description String[]
  stock Int
  onSale Boolean
  title String
  category Category @relation(fields: [categoryName], references: [categoryName])
  slug String @unique
  categoryName String


model Category
  id Int @id @default(autoincrement())
  image String
  categoryName String @unique
  animals Animals[]


model MainCards
  cardId Int @id @default(autoincrement())
  image String
  title String

typedefs--

const typeDefs = gql`
      type MainCard 
          title: String!
          image: String!
      
    
      type Animals
        id: ID!
        image: String!
        price: String!
        description: [String!]!
        stock: Int!
        onSale: Boolean
        slug: String
        categoryName: String
        title: String
      
    
      type Category
        id: ID!
        image: String!
        categoryName: String!
      
    
      type Query 
        mainCards: [MainCard]
        animals: [Animals]
        animal(slug: String!): Animals
        categories: [Category]
        category(categoryName: String!): [Animals]
      
    `;

要添加的部分数据:

const AnimalsData = async () => 
    await prisma.animals.createMany(
        data: [
            
                image: "lion",
                title: "7-year Male Lion with Large Well Kept Main with a Beautiful Yellow/Brownish Color",
                price: "23,322",
                description: [
                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
                    "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
                    "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
                    "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
                ],
                stock: 14,
                onSale: false,
                slug: "lion",
                categoryName: "cats"
            ,            
            
                image: "gorilla",
                title: "Black Haired Gorilla with Broad Chest and Shoulder. Would be an Excellent Spot at the Gym",
                price: "47,775",
                description: [
                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
                    "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
                    "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
                    "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
                ],
                stock: 14,
                onSale: false,
                slug: "gorilla",
                categoryName: "mammals"
                        
        ]
    )


AnimalsData()
.catch(e => throw e)
.finally(async () => await prisma.$disconnect())

如果有任何帮助,我将使用 prisma 2.24、apollo 和 graphql 以及 postgres 数据库。 非常感谢任何帮助或建议。

【问题讨论】:

【参考方案1】:

如果Category 表中没有具有相同categoryName 的匹配记录,Prisma 将不允许您使用Animals.categoryName 中提供的某个外键创建Animal 记录。这称为外键约束。

要满足外键约束,您需要确保Category 表中已经存在一条记录,该记录与您尝试在Animals 表中创建的记录具有相同的categoryName。对于您提到的示例,这意味着在Category 表中创建两条记录,其中包含“哺乳动物”和“猫”的Category.categoryName

在运行animals.createMany 查询之前,您可以执行以下操作,

await prisma.category.createMany(
        data: [
            
                categoryName: "mammals",
                image: "__PLACEHOLDER_VALUE__"  // change appropriately
            ,
            
                categoryName: "cats",
                image: "__PLACEHOLDER_VALUE__"  // change appropriately
            
        ]
    )

//  ...run await prisma.animals.createMany 

不可能使用单个 createMany 查询同时创建 AnimalCategory,因为您是 cannot access relations in a CreateMany query。如果这是您想要做的事情,请考虑使用create 而不是createMany。您可以在 Prisma 文档的 nested writes 部分找到更多相关信息。

【讨论】:

以上是关于如何在 prisma 中使用带有外键的 createMany?的主要内容,如果未能解决你的问题,请参考以下文章

为什么在Django上使用bulk_create插入带有外键的数据会返回“属性对象不可调用”?

如何在不同的数据库中使用带有外键的 django 模型?

如何在DJANGO里,向有外键的DB里插入数据

C# Entity Framework Code-First-如何仅使用该外键的 id 添加带有外键的行?

如何在 phpmyadmin 中显示外键的内容

插入带有外键的查询