TypeORM:更改主键长度后出现重复输入错误

Posted

技术标签:

【中文标题】TypeORM:更改主键长度后出现重复输入错误【英文标题】:TypeORM: duplicate entry error after changing length of primary key 【发布时间】:2021-09-24 10:01:49 【问题描述】:

我正在使用 Nestjs、mysql 和 Typeorm 为电子邮件制作表格。我的 char 类型主键长度为 39,并放置了一个由 UUID 连接组成的唯一字符串,其中包含一些额外的字符串。 这是我在名为“电子邮件”的 Nestjs 实体文件中使用 Typeorm 创建主键的方法。其中没有@PrimaryColumn 或@PrimaryGeneratedColumn。

@Column(
  primary: true,
  type: 'char',
  length: 39,
)
id: string;

表中有一些数据。在我将长度从 39 更改为 45 并运行服务器后,TypeOrmModule 发生错误。我没有尝试保存任何东西。奇怪的是,我在通过谷歌搜索插入数据时看到了类似的错误。

QueryFailedError: Duplicate entry '' for key 'email.PRIMARY'

即使我将长度重新设置为 39,仍然会发生错误。我发现运行服务器的唯一方法是删除表并创建一个新表。

我有 2 个关于此错误的问题。

    有没有办法改变主键的长度,保留表中的数据,运行服务端? '' - 错误语句中的空字符串 - 如何影响主键的唯一性?

【问题讨论】:

你的 Typeorm 配置对象中是否将 synchronize 设置为 true @hamidsajjadi 是的,我有 【参考方案1】:

我的猜测是您的 Typeorm 配置对象中有 synchronize: true。 并基于Typeorm documents

指示是否应在每次应用程序启动时自动创建数据库架构。请谨慎使用此选项,不要在生产中使用它 - 否则您可能会丢失生产数据。

所以实际发生的情况是,当您更改列的长度并启动应用程序时,typeorm 会尝试同步此更改并更新您的架构。出于here 提到的原因,Typeorm 通过完全删除该列并创建一个新列来实现这一点,但它会遇到重复错误。

    对于您的第一个问题,您可以使用migrations 来更好地控制架构的更新方式。虽然我应该提到,在迁移中 typeorm 的行为类似并删除了更改的列,但至少您可以自己编辑迁移文件以确保它执行您希望它执行的操作。或者您可以直接编辑数据库的架构。无论您选择做什么,synchronize 可能都不是一个好主意,除非是在开发的早期阶段。

    作为您的第二个问题,由于您的主列是没有默认值的char,因此新列值将正常填充'',对于不可为空的字段,默认为char;但显然它在唯一性也是最多的主列上遇到重复错误;因此错误Duplicate entry '' for key 'email.PRIMARY'

【讨论】:

感谢您的回答。因此,迁移让我在同步更改表和添加列的同时更改表和更改列,这就是现有数据将填充“”的原因... 是的。迁移将为您创建 sql 命令,您可以修改它们并选择是否要将它们应用于您的 db ,所以是的,您可以根据需要更改它们。 Synchronize 在您不知情的情况下在后台执行相同的操作,因此您将无法控制它。在这种情况下,它正在删除并重新创建列以应用您的更改。

以上是关于TypeORM:更改主键长度后出现重复输入错误的主要内容,如果未能解决你的问题,请参考以下文章

TypeORM 在批量保存时抛出重复错误,而不是忽略或更新现有值

PostgreSQL 与 TypeORM 错误“在 \"Sep\" 处或附近出现语法错误”

在 TypeORM 上接收“QueryFailedError:重复键值违反唯一约束”“pg_type_typname_nsp_index”错误

接口调用经常出现主键重复错误

在 Typeorm 中引用实体的复合主键

错误:使用 Nestjs + Graphql + Typeorm 时无法确定 GraphQL 输入类型