Генерируемые дубликаты идентификаторов нарушают ограничения первичного ключа - PullRequest
4 голосов
/ 13 ноября 2010

Может кто-нибудь помочь объяснить это? Я использую гемы Populator и Faker, чтобы поместить некоторые сгенерированные данные в мою базу данных. Помимо прочего, я генерирую 10 000 комментариев (которые взяты из гема act_as_commentable). Все это работает. Однако, когда я иду, чтобы добавить новый комментарий, я получаю сообщение об ошибке, что я нарушаю первичный ключ, используя существующий идентификатор Посмотрите на вывод моей консоли ниже. Вы можете видеть, что у меня есть 10000 записей, начинающихся с идентификатора 1 и заканчивающихся идентификатором 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 пакетирует записи в базу данных. Это происходит только на моделях / таблицах, которые я вижу в Populator.

Ответы [ 3 ]

5 голосов
/ 13 ноября 2010

Это происходит, если значение столбца id явно задано в операторе вставки.

Для каждого столбца id есть последовательность в Postgres, которая обычно называется tablename_columnname_seq, например user_id_seq.

Пожалуйста, проверьте имя в определении таблицы в pgadmin3, поскольку rails не поддерживает последовательности с другими именами.

Вы можете исправить последовательность со слишком низким идентификатором, выполнив что-то похожее на:

SELECT setval('user_id_seq', 10000);

Чтобы узнать наибольшее число: ВЫБЕРИТЕ макс (id) ИЗ пользователей;

SELECT max(x) FROM 
   (SELECT max(id) As x FROM users
    UNION SELECT last_value As x FROM user_id_seq As y);
0 голосов
/ 04 декабря 2013

Это удобный скрипт PostreSQL для исправления последовательностей для всех таблиц одновременно

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 голосов
/ 13 ноября 2010

Я не знаю, в чем собственно проблема, но она, безусловно, связана с использованием гема Populator для добавления записей. Генерация данных с помощью:

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

...