【问题标题】:Prisma with psql db - incompatible types: text and uuidPrisma 与 psql db - 不兼容的类型:文本和 uuid
【发布时间】:2022-04-11 13:28:56
【问题描述】:

我正在尝试学习如何将 prisma 与 psql 数据库一起使用。

我在使用 id 为 uuid 字符串的引用时遇到了问题。

我有一个用户模型:

model User {
  id        String   @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
  request   Request?
  createdAt DateTime @default(now()) @db.Timestamptz(6)
  updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
}

model Request {
  id                Int @id @default(autoincrement())
  user              User   @relation(fields: [id], references: [id])
  // I also tried making the relation field userId
  createdAt         DateTime @default(now()) @db.Timestamptz(6)
  updatedAt         DateTime @default(now()) @updatedAt @db.Timestamptz(6)
}

当我尝试迁移它时,我收到一条错误消息:

未能完全应用到影子数据库。错误:数据库错误: 错误:外键约束“Request_userId_fkey”不能 实施细节:关键列“userId”和“id”不兼容 类型:文本和 uuid。

prisma 文档没有显示使用 uuid 的示例。

他们给出的示例在 Profile 模型中具有第二个参数,其中 userId 作为 Int。我尝试将它添加到我的请求模型中(作为 int、作为字符串和作为 uuid)。这些都不起作用。

model User {
  id      Int      @id @default(autoincrement())
  email   String   @unique
  name    String?
  role    Role     @default(USER)
  posts   Post[]
  profile Profile?
}

model Profile {
  id     Int    @id @default(autoincrement())
  bio    String
  user   User   @relation(fields: [userId], references: [id])
  userId Int
}

如何在使用 uuid 生成 userId 时引用它?

segment of the prisma documentation 建议(如果我理解正确的话),任何 String 或 Int 或 enum 都应该能够识别 uuid:

关系型数据库对应数据库类型:PRIMARY KEY

可以用 @default() 值注释,该值使用函数来 自动生成 ID:

autoincrement() cuid() uuid() 可以在任何标量字段上定义 (字符串,整数,枚举)

当我尝试将 pgcrypto 扩展添加到 psql 时,我尝试再次运行迁移并得到一个错误消息较少,但仍然是类似的问题:

解析属性“@relation”时出错:id 中的字段类型 模型Request 与引用字段id 的类型不匹配 在模型User.

我见过this discussion,这表明以某种方式对棱镜撒谎。我不够聪明,无法理解谎言应该是什么或如何做到这一点。

github 上有人建议在请求模型中使用这种引用语法:

user                   User                      @relation(fields: [userId], references: [id])
userId                 String                    @unique    @db.Uuid

我按照上面的方法进行了尝试,但没有使用 @unique 标志,但我仍然收到迁移错误,提示 uuid 和 text 是不兼容的引用。我找不到解决如何使 uuid 引用与关系模型兼容的 prisma 文档部分。

fyi:上述尝试的迁移文件显示以下内容:

CREATE TABLE "Request" (
    "id" SERIAL NOT NULL,
    "userId" UUID NOT NULL,
    
    CONSTRAINT "Request_pkey" PRIMARY KEY ("id")
);

【问题讨论】:

  • 我认为这个问题与prisma schama中的问号有关。我找不到那个角色做什么的定义。没有 和 有什么区别!并且存在一个?但是,使用 ?创建与上面的错误消息一起显示的问题。我还没有找到解决方案......只是一个线索

标签: psql prisma prisma-graphql


【解决方案1】:

您必须在参考列userId 上使用注释@db.Uuid,阅读more about it here

例子:

model Request {
  id                Int @id @default(autoincrement())
  user              User   @relation(fields: [userId], references: [id])
  userId            String @db.Uuid
  ...your other stuff
}

【讨论】:

  • 我看不出您的建议与我在帖子中显示的尝试有什么区别。
  • 你必须写userId String @db.Uuid而不是userId String。如果不附加 @db.Uuid,列类型将是 TEXT 而不是 UUID
【解决方案2】:

我遇到了类似的错误,这是因为我没有将示例中的关系 ID 的类型从 Int 更改为 String

如果您将 Request 模型更新为如下所示,它可以工作吗?

model Request {
  id                Int @id @default(autoincrement())
  user              User   @relation(fields: [id], references: [id])
  userId            String // <- this was missing
  createdAt         DateTime @default(now()) @db.Timestamptz(6)
  updatedAt         DateTime @default(now()) @updatedAt @db.Timestamptz(6)
}

【讨论】:

  • 谢谢。您的建议与我从 github 推荐中分享的类似。虽然我尝试了它,但它会产生与上述相同的错误。感谢您分享对您有用的方法。太奇怪了,没有一个公开的原则来说明如何做到这一点。
【解决方案3】:

在您的请求模型中缺少外键userId@db.Uuid,这将使postgreSql 在列上使用uuid 类型,并且@relation 字段名称必须与@relation(fields: [userId]) 这样的外键相同。完整的代码应该是这样的:

model User {
  id        String   @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
  request   Request?
  createdAt DateTime @default(now()) @db.Timestamptz(6)
  updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
}

model Request {
  id        Int      @id @default(autoincrement())
  user      User     @relation(fields: [userId], references: [id]) <-ADD userId here
  userId    String   @db.Uuid <-ADD THIS
  createdAt DateTime @default(now()) @db.Timestamptz(6)
  updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
}

你可以用其他类型做到这一点,这里有一些例子:https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#string

【讨论】:

    【解决方案4】:

    我认为 Felix Hagspiel answer 是解决方案。我可以添加您应该删除失败的生成迁移 sql(通过删除文件夹)并在解决问题后重试。

    【讨论】:

      猜你喜欢
      • 2022-01-11
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2013-05-02
      • 2020-06-30
      • 2015-03-27
      • 2022-01-22
      相关资源
      最近更新 更多