【问题标题】:Rails: PG::UndefinedTable: ERROR: relation "..." does not existRails:PG :: UndefinedTable:错误:关系“...”不存在
【发布时间】:2015-07-29 04:38:03
【问题描述】:

在迁移时,我收到以下错误消息:

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

对于 Actioncodes,我有迁移文件:

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。我已将其迁移文件添加到原始帖子中
  • 看起来CreateOrganizations 迁移在执行CreateActioncodes 之前正在运行。 - CreateActioncodes 将首先运行,从而确保 actioncodes 表存在。
  • 你能否建议我应该如何改变这个?我检查了一下,SQL 代码确实确认在 Actioncodes 之前创建了 Organizations。
  • 我认为我需要一个额外的/新的迁移文件来创建引用:t.references :actioncode, index: true, foreign_key: true。然后从当前组织迁移文件中手动删除该行。但是创建附加/新迁移文件的命令是什么?

标签: ruby-on-rails postgresql ruby-on-rails-4 rails-migrations


【解决方案1】:

所以问题正在发生,因为在执行 CreateActioncodes 之前正在运行 CreateOrganizations 迁移。

CreateActioncodes 将首先运行,从而确保action codes 表存在。

迁移的运行顺序基于迁移的时间戳 - 如文件名所示。 20141014183645_create_users.rb 将在 20141014205756_add_index_to_users_email.rb 之前运行,因为第二个时间戳 - 20141014205756 在第一个时间戳之后 - 20141014183645

确保CreateOrganizations 迁移的时间戳在CreateActioncodes 迁移之后。

您可以手动更改文件名中的时间戳。或者删除这些迁移文件,然后按照正确的顺序创建它们。

【讨论】:

  • 这成功了!我使用rails generate migration AddActioncodeToOrganizations actioncode:references 创建了一个新的迁移文件以供参考。从旧迁移文件(我为其他变量保留)中删除了引用。 @mu 的回答太短当然也是正确的,但@Prakesh 只是早一点,所以我接受了这个作为解决方案。
  • 谢谢 - 生成数据库模型时很容易忽略的东西
【解决方案2】:

这一行中的foreign_key: true

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

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

constraint 指定一列(或一组列)中的值必须与另一个表的某一行中出现的值匹配。我们说这维护了两个相关表之间的参照完整性

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      在 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
      

      而且效果很好。

      就是这样。

      我希望这会有所帮助

      【讨论】:

        猜你喜欢
        • 2016-03-18
        • 1970-01-01
        • 2020-05-08
        • 2021-03-03
        • 1970-01-01
        • 1970-01-01
        • 2013-10-06
        • 2021-02-05
        相关资源
        最近更新 更多