【问题标题】:Rails Duplicate key error: How to tell Rails to continue with the ID from the databaseRails Duplicate key 错误:如何告诉 Rails 继续使用数据库中的 ID
【发布时间】:2020-10-21 06:35:33
【问题描述】:

我目前正在使用Postgres 部署一个Ruby on Rails Web 应用程序。我正在与Docker 合作,只是说出来。

当我部署我的应用程序时,我将一些预定义的数据插入到数据库中。当我想创建一条新记录时,我得到一个duplicate key error

完整的错误信息:

ERROR: duplicate key value violates unique constraint "modelname_pkey"
DETAIL: Key (id)=(1) already exists

我该如何解决这个问题?如何让 Rails 继续使用最后一条记录中的 primary key

【问题讨论】:

  • 您需要特殊 ID 吗?

标签: ruby-on-rails ruby postgresql docker ruby-on-rails-6


【解决方案1】:

您可以检查 Rails 6 中的 insert_all 方法。如果您使用的是较低版本的 Rails,请使用 activerecord-import gem。

insert_all 的情况

首先形成json

new_records = [{id: 1, name: 'steve'},{id: 2, name: 'george'}]
Model.insert_all(new_records)

如果记录不存在则插入记录,如果记录存在则忽略。

在主动记录导入的情况下

new_records = [{id: 1, name: 'steve'},{id: 2, name: 'george'}]
Model.import new_records, on_duplicate_key_ignore: true

参考: activerecord-import
rails-6-insert_all

【讨论】:

  • 如果 ID 1 或 2 已经被占用,这仍然会中断。
  • 如果 id 已经存在,如果需要更新数据,这将忽略新的更改,然后 upsert_all 或 upsert 可以使用 rails 6 并且对于 activerecord-import 我们可以使用标志 on_duplicate_key_update: [attributes_that_needs_to_be_updated] 而不是on_duplicate_key_ignore: true
  • 如果你使用on_duplicate_key_ignore,导入会悄悄地失败,你不知道是什么占用了这些ID。如果您使用on_duplicate_key_update,您已经替换了可能已经有关联的现有行。如果你真的需要那些特定的 ID(这表明它是如何变得复杂的),首先删除它们以确保它们被真正擦除然后导入可能更安全。
  • on_duplicate_key_update 将仅更新我们指定的属性,因此除非指定,否则它不会更新任何 id。根据需要可以使用 on_duplicate_key_ignore 或 on_duplicate_key_update
【解决方案2】:

如果您不指定 ID,数据库将为您选择一个。

person = Person.create!( name: "MacReady", thing: false )

如果您需要引用特定 ID,请重新考虑。正如您所发现的,依赖特殊 ID 太脆弱了。数据库 ID 应被视为没有其他特殊含义的唯一标识符。

例如,不要记住“用户 ID 1 是管理员用户”,而是添加一个“管理员”字段。

admin = User.create!( name: "Yarrow Hock", admin: true )

现在您可以为任何用户检查if user.admin,拥有任意数量的管理员,并随时更改用户是否为管理员。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    相关资源
    最近更新 更多