开发者

Duplicate ID's being generated violating primary key contraints

开发者 https://www.devze.com 2023-01-24 17:41 出处:网络
Can anyone help explain this? I am using the Populator and Faker gems to put some generated data into my database. Among other things, I generate 10,000 comments (which are from the \'acts_as_commenta

Can anyone help explain this? I am using the Populator and Faker gems to put some generated data into my database. Among other things, I generate 10,000 comments (which are from the 'acts_as_commentable' gem. All this works. However, when I go to add a new comment, I get an error saying that I am violating the primary key by using an existing id. Look at my console output below. You can see I have 10,000 records starting with ID 1 and ending with ID 100000. I then try to add a new comment and it fails. This is only happening with this model/table. I can add new users, etc.

>> 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.

I suspect this is related to how the Populator gem is batching the records into the database. It is only happening on models/tables that I see with Populator.


This happens if the value of the id column is explicitly set in an insert statement.

For every id-column there is a sequence in Postgres, which is usually named tablename_columnname_seq, for example user_id_seq.

Please check the name in the table definition in pgadmin3 as rails does not support sequences with other names.

You can fix a sequence with a too low id by executing something similar to:

SELECT setval('user_id_seq', 10000);

To learn the highest number: 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);


I do not know what the actual problem is, but it is certainly linked to using the Populator gem to add records. Generating data by using:

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

is fine.

However, generating records like

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

Something in there is causing my problem. note that I am using Rails 3.0.1


This is a handy PostreSQL script to fix sequences for all tables at once

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;
0

精彩评论

暂无评论...
验证码 换一张
取 消