Получение неизвестного первичного ключа для таблицы, пока есть идентификатор

Я отлаживал эту странную проблему, связанную с тем, что Rails давал мне "Неизвестный первичный ключ для таблицы...", даже когда идентификатор таблицы присутствует.

Я скопировал базу данных из одного приложения heroku в другое, в исходной базе данных проблем нет, а новая выдает ошибку db.

Это ошибка:

ProductsController# (ActionView::Template::Error) "Unknown primary key for table collections in model Collection."

/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/reflection.rb:366:in `primary_key'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/reflection.rb:480:in `association_primary_key'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/association_scope.rb:58:in `block in add_constraints'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/association_scope.rb:39:in `each'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/association_scope.rb:39:in `each_with_index'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/association_scope.rb:39:in `add_constraints'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/association_scope.rb:31:in `scope'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/association.rb:98:in `association_scope'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/association.rb:87:in `scoped'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:573:in `first_or_last'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/collection_association.rb:105:in `last'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/collection_proxy.rb:46:in `last'
/app/app/helpers/likes_helper.rb:62:in `significant_liker'

Строка, которая вызывает это:

product.collections.last.try :user

и таблица:

d8apjspa441pad=> \d collections
                                     Table "public.collections"
     Column     |          Type          |                        Modifiers                         
----------------+------------------------+----------------------------------------------------------
 id             | integer                | not null default nextval('collections_id_seq'::regclass)
 name           | character varying(255) | 
 user_id        | integer                | 
 permalink      | character varying(255) | 
 category_id    | integer                | 
 products_count | integer                | 
 is_featured    | boolean                | 
Indexes:
    "index_lists_on_user_id_and_permalink" UNIQUE, btree (user_id, permalink)

Любая идея, почему это может произойти?

Спасибо!


person hakunin    schedule 05.08.2013    source источник
comment
Кажется, в коллекциях отсутствует индекс первичного ключа.   -  person Debadatt    schedule 05.08.2013
comment
Можете ли вы поделиться для меня и других, как установить это в ответ?   -  person hakunin    schedule 05.08.2013


Ответы (12)


Кажется, для коллекций таблиц отсутствует первичный ключ.

До Rails 3.2 задайте первичный ключ в модели, например

class Collection < ActiveRecord::Base
  set_primary_key "my_existing_column"
end

В Rails 3.2+ и Rails 4 установите первичный ключ в модели, например

class Collection < ActiveRecord::Base
  self.primary_key = "my_existing_column"
end

ИЛИ

Мы можем изменить таблицу и установить первичный ключ для идентификатора, например

Создайте файл миграции, чтобы установить первичный ключ

class AddPrimaryKeyToCollections < ActiveRecord::Migration
 def change
   execute "ALTER TABLE collections ADD PRIMARY KEY (id);"
 end
end
person Debadatt    schedule 05.08.2013
comment
Хм, я думал, вы имеете в виду настройку первичного ключа в БД, это то, что я сделал, и хотя оно жаловалось на то, что ключ уже установлен, приложение заработало. Можете ли вы объяснить, почему я бы использовал set_primary_key, даже если идентификатор по умолчанию просто id? Может пригодиться. - person hakunin; 05.08.2013
comment
Возможно, в вашей таблице коллекций отсутствует один индекс первичного ключа в db. Каждая таблица должна иметь первичный ключ. Поскольку таблица здесь теряет первичный ключ, нам нужно его настроить. Но идентификатор по умолчанию не может быть установлен в качестве первичного ключа... поэтому возникает исключение. - person Debadatt; 05.08.2013
comment
По сути, у меня было два варианта — явно указать Rails или правильно настроить атрибут DB, верно? Если вы добавите PSQL для настройки атрибута, я приму ваш ответ. - person hakunin; 06.08.2013
comment
Пользователи Rails 4: self.primary_key = 'my_existing_column' вместо - person hammady; 02.02.2015

У меня была аналогичная проблема, и это была единственная страница, которую я мог найти. Так что на всякий случай, это поможет кому-то еще...

Я начал внезапно получать отсутствующие сообщения первичного ключа на паре таблиц. Я предполагаю, но не уверен, что это началось после отправки данных (pg_dump local, heroku pg:restore)

Оба рассматриваемых первичных ключа находились в таблицах, которые были переименованы, так что имя pkey не совпадало с именем таблицы, но, с другой стороны, множество других переименованных таблиц находились в той же лодке и не имели проблем.

В любом случае, в какой-то момент я попытался загрузить другой файл дампа и заметил некоторые жалобы на неправильные индексы. Сначала он пытался удалить их и жаловался, что не может, потому что их не существует. Позже он попытается их создать и будет жаловаться, что не может, потому что они уже существуют.

Очень раздражает, учитывая, что информация о pkey не отображается в schema.rb и должна «просто работать», верно?

В любом случае, что сработало для меня (и, следовательно, причина, по которой я публикую), это сделать heroku pg:reset, а затем снова загрузить дамп. Кстати, я получил «внутреннюю ошибку сервера» в первые два раза, когда попробовал heroku pg:reset. Но позже я попробовал еще раз, и это сработало.

person elc    schedule 14.08.2013

TL;DR: попробуйте перезапустить приложение.

Недавно я столкнулся с этой ошибкой: Неизвестный первичный ключ для таблицы, и, как и задающий вопрос, он появился после копирования базы данных в приложение Heroku.

В скопированной базе данных не было ошибок, поэтому я был уверен, что таблица и первичный ключ в порядке.

Я попробовал несколько предложений на этой странице, в том числе начать с нуля с heroku pg:reset, новой pg_dump старой базы данных и pgbackups:restore в новую базу данных, а затем выполнить миграцию и заполнение... ничего не получилось.

Что, наконец, решило мою проблему, так это перезапуск приложения. В новом приложении было много миграций базы данных, и запуск heroku restart перезагрузил схему и принял изменения схемы. Эта страница из документации Heroku объясняет:

Выполнение команд Rake

После запуска миграции вы захотите перезапустить свое приложение с помощью перезапуска heroku, чтобы перезагрузить схему и получить все изменения схемы.

person Jake Worth    schedule 16.07.2014
comment
Простой перезапуск также помог мне с этой ошибкой после развертывания capistrano. - person GSP; 18.07.2016
comment
heroku pg:reset тогда у меня сработал повторный импорт БД. Я вручную создал индекс в рабочей БД, и он неправильно копировался в промежуточную БД. - person Josh; 20.12.2017

Я восстанавливал дамп базы данных из героку в свою локальную систему и получал эту ошибку.

ActiveRecord::UnknownPrimaryKey: ActiveRecord::UnknownPrimaryKey

Я восстанавливал существующую базу данных, поэтому я удалил базу данных, создал новую базу данных, а затем восстановил дамп, и это сработало для меня.

person rubyonrails3    schedule 28.02.2017
comment
Также работает повторная загрузка схемы и восстановление дампа. - person puerile; 04.08.2020

Что мне помогло (произошло на героку после восстановления базы данных), так это переиндексация индекса первичного ключа:

reindex index $primary_key_index_name

person Michiel de Mare    schedule 15.04.2015
comment
Где вы это печатаете? - person Mark Swardstrom; 29.10.2015
comment
В консоли psql. - person Michiel de Mare; 30.10.2015
comment
Я получал ошибку в производстве (на Heroku) после нажатия. Не уверен, что у меня есть доступ к консоли БД. Повторное нажатие на Heroku, казалось, исправило это. Спасибо, что указали мне правильное направление. - person Mark Swardstrom; 30.10.2015
comment
Переиндексация тоже решила мою проблему (хотя мое приложение не размещено на Heroku). Главное здесь — не забыть перезапустить приложение. - person Alexander Kuznetsov; 21.01.2016

перезапуск сервера heroku сработал для меня. Возможно, это был spring-preloader, который распознавал пустую схему базы данных во время восстановления базы данных.

person loybert    schedule 24.09.2018

То же самое происходит и со мной при импорте дампа данных из героку в локальный. У меня есть Rails 5.1.6 для приложения. После добавления self.primary_key = "id" ко всем моделям, которые показывают проблему, у меня все работает нормально.

person Piyush Chaudhary    schedule 07.06.2020

Если вы пытаетесь устранить эту проблему, внимательно проверьте свои журналы. Я заметил более раннюю ошибку, связанную с активом js, который не был предварительно скомпилирован. Это потерялось в стеке сообщений рендеринга.

После того, как я исправил проблему предварительной компиляции ресурсов, ошибка «Неизвестный первичный ключ для таблицы» больше не возникала.

Это было 100% определенно единственное, что я изменил.

person Undistraction    schedule 07.03.2014

У меня возникла эта проблема, и проблема оказалась в том, что в моей таблице почему-то не было индекса первичного ключа. Решение состояло в том, чтобы создать миграцию, которая добавила первичный ключ:

execute "ALTER TABLE appointment_reminder_text ADD PRIMARY KEY (id)"
person Jason Swett    schedule 10.08.2015

Спасибо, изменение индекса выше сработало для меня. Еще одно краткое замечание о том, как эта ошибка будет проявляться, если задействовано более сложное отношение:

ActiveRecord::StatementInvalid - PG::SyntaxError: ERROR:  zero-length delimited identifier at or near """"
LINE 1: ...CT "users".* FROM "users"  WHERE "benefits"."" IN ('1'...
person Nathan Bertram    schedule 28.04.2016

Я столкнулся с этой ошибкой при тестировании в RSPEC.

В моем случае я решил это, добавив/установив primary_key в моей модели Rails.

class Tablename < ApplicationRecord
   self.primary_key ="id" if Rails.env.test? #optional condition
   ......
end
person aldrien.h    schedule 29.04.2020

Вы должны перезагрузить схему в целевом приложении. Затем загрузите базу данных.

person puerile    schedule 04.08.2020