Migration to create table raises Mysql2::Error: Table doesn't exist

Migration to create table raises Mysql2::Error: Table doesn't exist

我用以下内容写了一个迁移:

class CreateTableSomeTable < ActiveRecord::Migration[5.1]
  def change
    create_table :some_tables do |t|
      t.references :user, foreign_key: true
      t.references :author, references: :user, foreign_key: true
      t.text :summary
    end
  end
end

这是一个正在创建数据库的基本迁移 table。但是:当我 运行 rails db:migrate 一条非常奇怪的错误消息中止迁移时:

Mysql2::Error: Table 'my_database.some_tables' doesn't exist: SHOW FULL FIELDS FROM 'some_tables'

就好像错误说它无法创建 table 因为 table 确实存在,这没有意义。

我看过并尝试过的东西:

我正在使用 rails 5.1.1 以及 mysql2 0.4.6

关于如何迁移到 运行 的任何提示?

我想出了一个变通办法,但我仍然很困惑。

日志文件中的错误消息并未准确指出问题所在。出于某种原因,它可能是 rails 5.1.1 或者它可能是 mysql2 0.4.6,但由于某种原因它不喜欢在 create_table 块中使用 references。很奇怪,因为它过去对我有用。

所以我从这里更改了迁移:

class CreateTableSomeTable < ActiveRecord::Migration[5.1]
  def change
    create_table :some_tables do |t|
      t.references :user, foreign_key: true
      t.references :author, references: :user, foreign_key: true
      t.text :summary
    end
  end
end

为此:

class CreateTableSomeTable < ActiveRecord::Migration[5.1]
  def change
    create_table :some_tables do |t|
      t.integer :user_id
      t.integer :author_id
      t.text :summary
    end
  end
end

它奏效了。

这很奇怪,因为 referencessqlite3 一起工作得很好(我通过生成一个虚拟应用程序测试了这个,运行 一个带有 references 列的脚手架命令和 运行 rails db:migrate 并且一切正常)。

我在尝试创建一个引用了迁移到 Rails 5.1 之前创建的现有模型的新模型时遇到了类似的错误。

虽然错误信息不是很清楚,但在我的例子中,问题是旧模型的主键和新模型的外键之间的数据类型不匹配(MySQL 不允许这样做)。是因为Rails 5.1以后所有主键和外键的默认数据类型都是bigint,但是对于旧的模型,主键类型仍然是整数。

我通过将当前模型的所有主键和外键转换为 bigint 解决了这个问题,因此我可以使用 Rails 新的默认值而忘记它。

解决方法还可以是为新外键指定整数类型,以便它们与旧模型的主键类型相匹配。类似于以下内容:

class CreateUserImages < ActiveRecord::Migration[5.1]
  def change
    create_table :user_images do |t|
      t.references :user, type: :integer, foreign_key: true
      t.string :url
    end
  end
end

这让我抓狂,我想我看到的原因与其他人建议的不同。就我而言,这是因为我的迁移文件名与其中的迁移 class 不完全匹配。例如,我有一个名为 20171205232654_bonus.rb 的迁移文件,但在 class 中被声明为 class CreateBonus < ActiveRecord::Migration[5.1]。一旦我将文件名更改为 20171205232654_create_bonus.rb 一切正常。

这可能与我只创建迁移,而不是完整的脚手架有关,也许我做错了什么。我真的不知道我是怎么结束这种不匹配的。

ActiveRecord 迁移 5.1 的最大问题是现在 id 应该是 BIGINT 而不是 INT,所以当你添加一个引用另一个 table 在 rails 5.1 之前创建的列时,它期望列类型为 BIGINT 但只是 INT,因此出现错误。 最好的解决方案就是修改您的迁移并将列的类型更改为 int。

class CreateTableSomeTable < ActiveRecord::Migration[5.1]
 def change
  create_table :some_tables do |t|
   t.references :user, foreign_key: true, type: :int
   t.references :author, references: :user, foreign_key: true
   t.text :summary
  end
end

应该可以。