在 ID 存在时获取“表的未知主键”
Posted
技术标签:
【中文标题】在 ID 存在时获取“表的未知主键”【英文标题】:Getting "Unknown primary key for table" while the ID is there 【发布时间】:2013-08-06 01:00:34 【问题描述】:我一直在调试 Rails 的这个奇怪问题,给我“表的未知主键...”,即使表的 ID 在那里。
我已将数据库从一个 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)
知道为什么会发生这种情况吗?
谢谢!
【问题讨论】:
似乎集合中缺少主键索引。 您能否为我和其他人的利益分享如何在答案中建立它? 【参考方案1】:似乎缺少表集合的主键。
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
或
我们可以修改表并为id设置主键
创建迁移文件设置主键
class AddPrimaryKeyToCollections < ActiveRecord::Migration
def change
execute "ALTER TABLE collections ADD PRIMARY KEY (id);"
end
end
【讨论】:
嗯,我以为你的意思是在数据库中设置主键,这就是我所做的,虽然它抱怨已经设置了键,但应用程序开始工作了。你能解释一下为什么我会使用set_primary_key
,即使ID 只是默认的id
?可能会派上用场。
可能您的集合表缺少数据库中的一个主键索引。每个表都应该有一个主键。由于此处的表丢失了主键,我们需要对其进行设置。但是默认 id 无法设置为主键.. 所以它会引发异常。
所以基本上,我有两个选择 - 明确告诉 Rails,或者正确设置 DB 属性,对吗?如果您添加 PSQL 来设置属性,我会接受您的回答。
Rails 4 用户:self.primary_key = 'my_existing_column'
代替【参考方案2】:
我遇到了类似的问题,这是我能找到的唯一页面。所以以防万一它对其他人有帮助......
我突然开始在几个表上丢失主键消息。我猜,但不确定,这是在推送数据后开始发生的(pg_dump local,heroku pg:restore
)
有问题的主键都在已重命名的表上,因此 pkey 名称与表名不匹配 - 但另一方面,许多其他重命名的表在同一条船上并且没有问题。
无论如何,在我四处游荡的时候,我尝试上传另一个转储文件,但我注意到一些关于违规索引的投诉。首先,它会尝试删除它们并抱怨它不能,因为它们不存在。后来它会尝试创建它们并抱怨它不能因为它们已经存在。
考虑到 pkey 信息没有显示在 schema.rb
中并且应该“正常工作”,这很烦人,对吧?
无论如何,对我有用的(以及我发帖的原因)是做一个heroku pg:reset
,然后再次加载转储。旁注,我在尝试heroku pg:reset
的前两次出现“内部服务器错误”。但后来我又试了一次,它成功了。
【讨论】:
【参考方案3】:如果您尝试解决此问题,请务必仔细检查您的日志。我注意到一个与未预编译的 js 资产相关的早期错误。这在渲染消息堆栈中丢失了。
一旦我修复了资产预编译问题,就不再抛出“Unknown primary key for table”错误。
这绝对是我唯一改变的 100%。
【讨论】:
【参考方案4】:TL;DR:尝试重启应用。
heroku restart
我最近遇到了这个错误:“Unknown primary key for table”,和提问者一样,它是在将数据库复制到 Heroku 应用后出现的。
复制的数据库没有错误,所以我确信表和主键都很好。
我在此页面上尝试了一些建议,包括从头开始使用旧数据库的 heroku pg:reset
、新的 pg_dump
和新数据库的 pgbackups:restore
,然后运行迁移和播种...没有任何效果.
最终解决我的问题是重新启动应用程序。新应用程序有许多数据库迁移,重新启动应用程序会重新加载架构并获取更改。 Heroku 文档中的这一页解释道:
Running Rake Commands
运行迁移后,您需要使用 heroku restart 重新启动应用以重新加载架构并获取任何架构更改。
【讨论】:
在 capistrano 部署后,只需重新启动也对我有用。heroku pg:reset
然后重新导入数据库对我有用。我在生产数据库上手动创建了一个索引,但它没有被正确复制到暂存数据库
heroku restart
也解决了我的问题【参考方案5】:
对我有帮助的(在 db 恢复后发生在 heroku 上)是重新索引主键索引:
reindex index $primary_key_index_name
【讨论】:
你在哪里输入这个? 在psql
控制台中。
推送后我在生产中(在 Heroku 上)遇到错误。不确定我是否可以访问数据库控制台。再次推送到 Heroku 似乎解决了它。感谢您为我指明正确的方向。
重新索引也解决了我的问题(虽然我的应用程序没有托管在 Heroku 上)。这里的要点是不要忘记重新启动您的应用程序。【参考方案6】:
我遇到了这个问题,结果是我的表不知何故实际上没有主键索引。解决方案是创建一个添加主键的迁移:
execute "ALTER TABLE appointment_reminder_text ADD PRIMARY KEY (id)"
【讨论】:
在将几个相同的数据库合并为一个以进行多租户设置后,这发生在我身上。我正在遵循一些我并没有真正深入理解的 SQL 指南。我可能错过了在该表上重新应用主键,或者它只是在恢复过程中被修改了。运行上面的代码,一切都很好!【参考方案7】:感谢更改上面的索引对我有用。如果涉及更复杂的关系,关于此错误将如何表现出来的另一个快速说明:
ActiveRecord::StatementInvalid - PG::SyntaxError: ERROR: zero-length delimited identifier at or near """"
LINE 1: ...CT "users".* FROM "users" WHERE "benefits"."" IN ('1'...
【讨论】:
【参考方案8】:我正在将数据库转储从 heroku 恢复到我的本地系统并收到此错误..
ActiveRecord::UnknownPrimaryKey: ActiveRecord::UnknownPrimaryKey
我正在恢复现有数据库,所以我删除了数据库,创建了新数据库,然后恢复了转储,它对我有用
【讨论】:
也重新加载架构然后恢复转储工作以及【参考方案9】:重新启动 heroku 服务器对我有用。也许是 spring-preloader 在 db-restorement 期间识别了空的 db-schema
【讨论】:
【参考方案10】:我在 RSPEC 中进行测试时遇到了这个错误。
在我的例子中,我通过在我的 Rails 模型中添加/设置 primary_key 解决了这个问题
class Tablename < ApplicationRecord
self.primary_key ="id" if Rails.env.test? #optional condition
......
end
【讨论】:
【参考方案11】:在将数据转储从 heroku 导入到本地时,同样的事情也发生在我身上。我有该应用程序的 Rails 5.1.6。
将self.primary_key = "id"
添加到所有显示问题的模型后,一切对我来说都很好。
【讨论】:
【参考方案12】:您应该在目标应用程序上重新加载架构。然后加载数据库。
【讨论】:
以上是关于在 ID 存在时获取“表的未知主键”的主要内容,如果未能解决你的问题,请参考以下文章