【问题标题】:Why is this Rails migration giving a 'no such table' error?为什么这个 Rails 迁移会给出“没有这样的表”错误?
【发布时间】:2020-11-06 11:27:29
【问题描述】:

在一个新的 Rails 6 项目中,我有一个名为 object_classes 的表,其中有一列名为 ClassList_id。来自 schema.rb:

 create_table "object_classes", force: :cascade do |t|
    t.string "name"
    t.integer "ClassList_id", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["ClassList_id"], name: "index_object_classes_on_ClassList_id"
  end

我意识到该列应该命名为 class_list_id 以符合 Rails 预期的命名约定。因此,我生成了一个新的迁移:

class FixColumnName < ActiveRecord::Migration[6.0]
  def change
    rename_column :object_classes, :ClassList_id, :class_list_id
  end
end

但是,当我运行此迁移时,我收到以下错误:

/bin/bash -c "env RBENV_VERSION=2.6.1 /home/asfarley/.rbenv/libexec/rbenv exec bundle exec ruby /home/asfarley/imgseq/bin/spring rails 'db:migrate'"
== 20200716060501 FixColumnName: migrating ====================================
-- rename_column(:object_classes, :ClassList_id, :class_list_id)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: no such table: main.ClassLists
/home/asfarley/imgseq/db/migrate/20200716060501_fix_column_name.rb:3:in `change'
/home/asfarley/imgseq/bin/rails:9:in `<top (required)>'
/home/asfarley/imgseq/bin/spring:15:in `require'
/home/asfarley/imgseq/bin/spring:15:in `<main>'

Caused by:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table: main.ClassLists
/home/asfarley/imgseq/db/migrate/20200716060501_fix_column_name.rb:3:in `change'
/home/asfarley/imgseq/bin/rails:9:in `<top (required)>'
/home/asfarley/imgseq/bin/spring:15:in `require'
/home/asfarley/imgseq/bin/spring:15:in `<main>'

Caused by:
SQLite3::SQLException: no such table: main.ClassLists
/home/asfarley/imgseq/db/migrate/20200716060501_fix_column_name.rb:3:in `change'
/home/asfarley/imgseq/bin/rails:9:in `<top (required)>'
/home/asfarley/imgseq/bin/spring:15:in `require'
/home/asfarley/imgseq/bin/spring:15:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

Process finished with exit code 1

我在这里做错了什么?我正在寻找一个解释,具体解决这里的问题,以便我可以理解将来如何避免这种情况。

【问题讨论】:

  • 这不是一个合适的符号,试试这个... rename_column :object_classes, "ClassList_id", :class_list_id
  • @dbugger 很有趣,我应该尝试过,但我已经通过以不同的方式更改迁移来修复它。对于未来未定义的外键约束的情况,我会牢记您的建议。
  • @dbugger 实际上,基于我的迁移在删除外键后工作的事实,我相信未定义的符号在这里不是问题。

标签: ruby-on-rails database-migration rails-migrations


【解决方案1】:

您的语法没有问题,因此错误必须是保留名称错误。可以尝试删除该列并再次创建该列,注意迁移时的大写字母,因为它们可能会使您的代码不必要地复杂化。试试这个:

rails g migration RemoveClassListIdFromObjectClasses

这将创建一个类似这样的迁移:

def drop 
    remove column :object_classes, :class_lis_id
end 

然后运行

rails g migration AddClassListIdToObjectClasses

迁移应该如下所示:

def change
    add_column :object_classes, :class_list_id
end

记得添加数据类型和您可能需要的任何其他内容。 在那里您可以检查它创建的迁移,您可以更改它以添加数据类型或更改列的大小写,然后您就可以开始了。

注意:如果它有效,如果您接受答案,我将不胜感激,谢谢!

【讨论】:

  • 不是保留名称错误;这是一个外键指向一个不存在的表。但是,我最终自己解决了这个问题,所以我无法确认这种方法是否也能解决这个问题。您删除列的方法可能会产生删除外键的副作用,这可以替代我的方法。
  • 很高兴听到您解决了这个问题。这不会是一个问题,因为您可以轻松地将外键再次添加到迁移中,并且不会破坏其他任何内容。
【解决方案2】:

很难知道故障是 Rails 还是 SQLite,但问题似乎是我为我的 object_classes 表定义了一个外键,指向一个不存在的表。通过这次迁移,我能够修复外键约束并重命名列:

class FixColumnName < ActiveRecord::Migration[6.0]
  def change
    remove_foreign_key :object_classes, :ClassLists
    rename_column :object_classes, :ClassList_id, :class_list_id
    add_foreign_key :object_classes, :class_lists
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    相关资源
    最近更新 更多