Ruby on rails 轨道&x2B;postgres自动增量未在显式id插入时更新

Ruby on rails 轨道&x2B;postgres自动增量未在显式id插入时更新,ruby-on-rails,postgresql,activerecord,Ruby On Rails,Postgresql,Activerecord,我也有同样的问题。但我使用的是Rails,不知道如何在activerecord中解决这个问题 我正在使用seeds.rb插入一些数据: device_platforms = DevicePlatform.create([{id: 1, name: 'Android'}, {id: 2, name: 'IOS'}, {id: 3, name: 'Windows Phone'}]) 当我插入另一个DevicePlatform时,会出现以下异常: Failure/Error: @device_pla

我也有同样的问题。但我使用的是Rails,不知道如何在activerecord中解决这个问题

我正在使用seeds.rb插入一些数据:

device_platforms = DevicePlatform.create([{id: 1, name: 'Android'}, {id: 2, name: 'IOS'}, {id: 3, name: 'Windows Phone'}])
当我插入另一个DevicePlatform时,会出现以下异常:

Failure/Error: @device_platform = FactoryGirl.create(:device_platform)
 ActiveRecord::RecordNotUnique:
   PG::UniqueViolation: ERRO:  duplicar valor da chave viola a restrição de unicidade "device_platforms_pkey"                                                                 
   DETAIL:  Chave (id)=(2) já existe.
   : INSERT INTO "device_platforms" ("created_at", "name", "updated_at") VALUES ($1, $2, $3) RETURNING "id"        
消息是葡萄牙语的,它表示具有该ID的行已经存在


谢谢。

根据评论,在seed中使用id是一种不好的做法。我在避免不良行为,这对我来说已经足够了。将我的代码更改为避免这种情况。

我相信,虽然这是一个坏习惯,但很多时候,这是唯一的解决办法

您可以定义此方法:

def fix_self_increment(model)
  ActiveRecord::Base.connection.execute(
    "BEGIN; " \
    "LOCK TABLE #{model.table_name} IN EXCLUSIVE MODE; " \
    "SELECT setval('#{model.table_name}_id_seq', COALESCE((SELECT MAX(id)+1 FROM #{model.table_name}), 1), false); " \
    "COMMIT;"
  )
end 
然后打电话

fix_self_increment(DevicePlatform)

享受

为什么要指定id?不要在种子中包含
id
s。如果您必须在种子中包含
id
s,那么您必须
连接。添加种子后,执行另一个问题中的SQL。感谢您提供错误的确切文本。如果可以的话,我会+100。@muistooshort你认为在种子文件中包含id是一种不好的做法吗?取决于
id
s,任何特别的东西都是一种不好的做法。如果需要,您可以这样做,但您需要运行一些SQL来修补用于提供
id
值的序列。仍然有可能发生这种情况的有效用例(例如,在rake任务中读取CSV文件),所以很高兴看到一个有效的答案来解决这个问题。请接受上面的答案,因为它确实回答了你提出的问题,尽管这是一个坏主意。有时做一些不好的事情是必要的,我会在每次迁移数据时使用这些代码来执行这种插入,而不是使用一个方法来执行。它会很快告诉你指定id是个坏主意。顺便说一句,这是正确的答案。