生成的重复ID违反主键约束

时间:2010-11-13 12:51:21

标签: ruby-on-rails postgresql acts-as-commentable

任何人都可以帮忙解释一下吗?我使用Populator和Faker宝石将一些生成的数据放入我的数据库。除此之外,我生成了10,000条评论(来自'acts_as_commentable'宝石。这一切都有效。但是,当我去添加新评论时,我收到一条错误消息,说我使用现有的id侵犯了主键看看我下面的控制台输出。你可以看到我有10,000条记录,从ID 1开始,以ID 100000结尾。然后我尝试添加一条新评论,但它失败了。这只发生在这个模型/表中。我可以添加新用户等。

>> Comment.first(:order => 'id').id
=> 1
>> Comment.last(:order => 'id').id
=> 10000
>> Comment.count
=> 10000
>> Comment.create(:title => 'wtf is up?')
ActiveRecord::RecordNotUnique: PGError: ERROR:  duplicate key value violates unique constraint "comments_pkey"
DETAIL:  Key (id)=(1) already exists.

我怀疑这与Populator gem如何将记录批量编入数据库有关。它只发生在我用Populator看到的模型/表格上。

3 个答案:

答案 0 :(得分:5)

如果在insert语句中显式设置了id列的值,则会发生这种情况。

对于每个id-column,Postgres中都有一个序列,通常名为tablename_columnname_seq,例如user_id_seq。

请检查pgadmin3中表定义中的名称,因为rails不支持具有其他名称的序列。

您可以通过执行类似以下的操作来修复ID过低的序列:

SELECT setval('user_id_seq', 10000);

要了解最高数字:     SELECT max(id)FROM users;

SELECT max(x) FROM 
   (SELECT max(id) As x FROM users
    UNION SELECT last_value As x FROM user_id_seq As y);

答案 1 :(得分:0)

我不知道实际问题是什么,但它肯定与使用Populator gem添加记录有关。使用以下方法生成数据:

Populator.sentences(1..3) # makes 3 sentences

很好。

然而,生成

等记录
User.populate 5000 do |user| # makes 5000 users in batches of 1000
   user.name = Populator.words(1)
   ...
end

那里的东西引起了我的问题。请注意我使用的是Rails 3.0.1

答案 2 :(得分:0)

这是一个方便的PostgreSQL脚本,可以同时修复所有表的序列

SELECT  'SELECT SETVAL(' ||quote_literal(quote_ident(S.relname))|| ', MAX(' ||quote_ident(C.attname)|| ') ) FROM ' ||quote_ident(T.relname)|| ';'
FROM pg_class AS S, pg_depend AS D, pg_class AS T, pg_attribute AS C
WHERE S.relkind = 'S'
AND S.oid = D.objid
AND D.refobjid = T.oid
AND D.refobjid = C.attrelid
AND D.refobjsubid = C.attnum
ORDER BY S.relname;