为啥 referentialIntegrity = "prisma" 不能防止迁移中的外键?

Posted

技术标签:

【中文标题】为啥 referentialIntegrity = "prisma" 不能防止迁移中的外键?【英文标题】:Why isn't referentialIntegrity = "prisma" preventing foreign keys in migrations?为什么 referentialIntegrity = "prisma" 不能防止迁移中的外键? 【发布时间】:2022-01-18 05:11:36 【问题描述】:

我正在尝试使用 prisma 和 PlanetScale 设置 nextAuth。 Planetscale 不允许外键,但 Prisma 允许禁用外键:https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-integrity

这个问题已被广泛讨论 (https://github.com/prisma/prisma/issues/7292),甚至还有一个看起来应该可行的示例 (https://templates.netlify.com/template/nextjs-planetscale-starter/)。

我已经设置了我的 planetscale 数据库并且可以连接到它。但是,当我尝试应用 NextAuth 模型时,我收到了这个错误:

$ npx prisma migrate dev

...
    
Database error code: 1317

Database error:
Foreign keys cannot be created on this database. Learn more how to handle this: https://pris.ly/d/migrate-no-foreign-keys

如果我使用 referentialIntegrety 标志,为什么 prisma 会尝试创建外键?我在这里遗漏或误解了什么?

schema.prisma 文件:


datasource db 
  provider             = "mysql"
  url                  = env("DATABASE_URL")
  shadowDatabaseUrl    = env("SHADOW_DATABASE_URL")
  referentialIntegrity = "prisma"


generator client 
  provider        = "prisma-client-js"
  previewFeatures = ["referentialIntegrity"]


model Account 
    id                       String   @id @default(cuid())
    createdAt                DateTime @default(now())
    updatedAt                DateTime @updatedAt
    userId                   String
    type                     String
    provider                 String
    providerAccountId        String
    refresh_token            String? @db.VarChar(500)
    access_token             String? @db.VarChar(500)
    refresh_token_expires_in Int?
    expires_at               Int?
    token_type               String?
    scope                    String?
    id_token                 String? @db.Text
    session_state            String?
    oauth_token_secret       String?
    oauth_token              String?

    user User @relation(fields: [userId], references: [id], onDelete: Cascade)

    @@unique([provider, providerAccountId])


model Session 
    id           String   @id @default(cuid())
    sessionToken String   @unique
    expires      DateTime
    user         User?    @relation(fields: [userId], references: [id], onDelete: Cascade)
    userId       String?


model User 
    id            String    @id @default(cuid())
    createdAt     DateTime  @default(now())
    updatedAt     DateTime  @updatedAt
    name          String?
    email         String?   @unique
    password      String?
    emailVerified DateTime?
    image         String?
    role          String?   @default("user")
    accounts      Account[]
    sessions      Session[]


model VerificationToken 
    identifier String
    token      String   @unique
    expires    DateTime

    @@unique([identifier, token])

$ npx prisma -v
Environment variables loaded from .env
prisma                  : 3.6.0
@prisma/client          : 3.6.0
Current platform        : darwin
Query Engine (Node-API) : libquery-engine dc520b92b1ebb2d28dc3161f9f82e875bd35d727 (at node_modules/@prisma/engines/libquery_engine-darwin.dylib.node)
Migration Engine        : migration-engine-cli dc520b92b1ebb2d28dc3161f9f82e875bd35d727 (at node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine    : introspection-core dc520b92b1ebb2d28dc3161f9f82e875bd35d727 (at node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary           : prisma-fmt dc520b92b1ebb2d28dc3161f9f82e875bd35d727 (at node_modules/@prisma/engines/prisma-fmt-darwin)
Default Engines Hash    : dc520b92b1ebb2d28dc3161f9f82e875bd35d727
Studio                  : 0.440.0
Preview Features        : referentialIntegrity

我们将不胜感激!提前致谢!

【问题讨论】:

【参考方案1】:

因为这个错误,我损失了几个小时。

睡觉并用新鲜的眼睛看了 5 分钟后,我意识到这是因为在我添加referentialIntegrity = "prisma" 和 previewFeatures = ["referentialIntegrity"] 之前已经创建了迁移文件。

课程:prisma 无法识别由此类配置更改引起的迁移差异。您必须删除受影响的迁移并重新创建它们。

【讨论】:

我在 Prisma 存储库中打开了一个问题,以便更好地处理这种情况:github.com/prisma/prisma/issues/10843【参考方案2】:

我已经复制了您的架构,并且我遵循了this 教程,并且一切正常。在图像中,您可以看到迁移成功。

顺便说一句:我的 prisma 版本是 3.3.0

【讨论】:

谢谢!我已经完成了这些步骤。我的问题是一个新手错误:在添加这些标签之前,我没有意识到迁移已经创建。我需要做的就是删除迁移并重新运行迁移。

以上是关于为啥 referentialIntegrity = "prisma" 不能防止迁移中的外键?的主要内容,如果未能解决你的问题,请参考以下文章

数据约束

Mysql基础02-约束

oracle入门数据完整性约束

你应该同步运行方法吗?为啥或者为啥不?

为啥使用 glTranslatef?为啥不直接更改渲染坐标?

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?