Rails:PG :: UndefinedTable:错误:关系“...”不存在。

11

迁移时我遇到了以下错误信息:

PG::UndefinedTable: ERROR:  relation "actioncodes" does not exist
: ALTER TABLE "organizations" ADD CONSTRAINT "fk_rails_4ecaa2493e"
FOREIGN KEY ("actioncode_id")
  REFERENCES "actioncodes" ("id")

我有一个关于组织的迁移文件如下:

class CreateOrganizations < ActiveRecord::Migration
  def change
    create_table :organizations do |t|
      t.string     :name,         null: false,    limit: 40
      t.references :actioncode,   index: true,    foreign_key: true
      t.boolean    :activated
      t.datetime   :activated_at

      t.timestamps null: false
    end
  end
end

对于操作码,我有迁移文件:

class CreateActioncodes < ActiveRecord::Migration
  def change
    create_table :actioncodes do |t|
      t.string  :code,          null: false,  limit: 20
      t.string  :description,                 limit: 255

      t.timestamps null: false
    end
  end
end
class AddIndexToActioncodesCode < ActiveRecord::Migration
  def change
    add_index :actioncodes, :code,  unique: true
  end
end

组织机构模型文件包含:belongs_to: actioncode
而actioncodes模型文件包括:has_many: organizations您知道是什么导致了错误消息吗? 如果我从迁移文件中删除index:true,foreign_key:true,它将在没有错误的情况下进行迁移。当我用不正确的行t.references:actioncode_id,index:true,foreign_key:true替换该行时,它会给出以下错误,其中最后一行(“ids”)表明Rails似乎有问题与表的名称?
PG::UndefinedTable: ERROR:  relation "actioncode_ids" does not exist
: ALTER TABLE "organizations" ADD CONSTRAINT "fk_rails_604f95d1a1"
FOREIGN KEY ("actioncode_id_id")
  REFERENCES "actioncode_ids" ("id")

表名为actioncodes。我已经将其迁移文件添加到原始帖子中。 - Nick
1
看起来 CreateOrganizations 迁移正在 CreateActioncodes 执行之前运行。应该先运行 CreateActioncodes,以确保 actioncodes 表存在。 - Prakash Murthy
你能否给我建议,我应该如何更改这个问题?我检查了SQL代码,确认Organizations确实是在Actioncodes之前被创建的。 - Nick
我认为我需要一个额外/新的迁移文件来创建引用:t.references :actioncode, index: true, foreign_key: true。然后手动从当前组织迁移文件中删除该行。但是,创建额外/新的迁移文件的命令是什么? - Nick
4个回答

21
因为 CreateOrganizations 迁移在执行 CreateActioncodes 之前运行,所以出现了这个问题。
应先运行 CreateActioncodes 以确保存在 action codes 表。
迁移的运行顺序基于迁移的时间戳,在文件名中表示。例如 20141014183645_create_users.rb 将在 20141014205756_add_index_to_users_email.rb 之前运行,因为第二个的时间戳 20141014205756 比第一个的时间戳 20141014183645 要晚。
请确保 CreateOrganizations 迁移的时间戳在 CreateActioncodes 迁移之后。可以手动更改文件名中的时间戳,或者删除这些迁移文件,并按正确的顺序创建它们。

1
这个方法可行!我使用了 rails generate migration AddActioncodeToOrganizations actioncode:references 来创建一个新的迁移文件以引用。从旧的迁移文件中删除了该引用(但保留了其他变量)。当然,@mu 的答案也是正确的,但@Prakesh更早一些,所以我接受了他的解决方案。 - Nick
感谢 - 在生成数据库模型时很容易被忽视的东西。 - Onichan
2022仍然运行良好。 - sksmsWKd

10

这一行中的foreign_key: true

t.references :actioncode,   index: true,    foreign_key: true

告诉Rails在数据库中创建一个外键。 外键:

约束条件指定列(或一组列)中的值必须与另一个表中某一行中出现的值相匹配。我们称之为维护两个相关表之间的引用完整性

因此,它是数据库内部的一些逻辑(属于数据库),确保您无法将无效值放入actioncode列,并且无法从正在使用其他地方的actioncodes表中删除条目。

为了创建约束条件,引用的表(actioncodes)需要在引用之前存在。看起来你的迁移尝试在actioncodes之前创建organizations,所以你只需要重命名CreateOrganizations迁移文件,使其时间戳前缀位于CreateActioncodes之后。前缀只是格式为YYYYMMDDhhmmss的时间戳,因此将CreateOrganizations时间戳更改为比CreateActioncodes多一秒的时间戳即可。


5

我也遇到了这个错误。如果你在使用测试数据库运行 rspec,请确保在运行 rspec 之前在终端中运行 rake db:test:prepare


0

在 Ubuntu 20.04 上开发 Rails 6 应用时,我也遇到了同样的挑战。

我正在开发一个学院门户网站,其中有一个名为 School 的模型和另一个名为 Program 的模型。模型 Program 属于模型 School,因此需要向 programs 表中添加一个 school 引用列。

我使用了以下命令创建迁移文件:

rails generate model School name:string logo:json motto:text address:text

rails generate model Program name:string logo:json motto:text school_id:references

然而,当我运行命令:rails db:migrate时,
我收到了以下错误提示:
== 20201208043945 CreateSchools: migrating ====================================
-- create_table(:schools)
   -> 0.0140s
== 20201208043945 CreateSchools: migrated (0.0141s) ===========================

== 20201208043958 CreatePrograms: migrating ===================================
-- create_table(:programs)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR:  relation "school_ids" does not exist
这是我解决问题的方法
问题出在命令行上:
rails generate model Program name:string logo:json motto:text school_id:references

应该是 school:references 而不是 school_id:references,所以在迁移时 Rails 找不到表 school_ids

因此,我修改了命令为:

rails generate model Program name:string logo:json motto:text school:references

它工作得很好。

就是这样了。

希望这有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接