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 确实存在,这没有意义。
我看过并尝试过的东西:
- 查看了 database.yml,看起来不错。什么都没有改变,我最近 运行 其他迁移也很好(尽管没有创建数据库的迁移 tables)
- 运行
bundle
确保安装了所有 gem
- 删除了
schema.rb
文件,用另一个副本的数据重新创建了数据库,我 运行 rake db:schema:dump
重新创建了 schema.rb
文件。我再次尝试 运行 迁移,但仍然出现相同的错误。
我正在使用 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
它奏效了。
这很奇怪,因为 references
与 sqlite3
一起工作得很好(我通过生成一个虚拟应用程序测试了这个,运行 一个带有 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
应该可以。
我用以下内容写了一个迁移:
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 确实存在,这没有意义。
我看过并尝试过的东西:
- 查看了 database.yml,看起来不错。什么都没有改变,我最近 运行 其他迁移也很好(尽管没有创建数据库的迁移 tables)
- 运行
bundle
确保安装了所有 gem - 删除了
schema.rb
文件,用另一个副本的数据重新创建了数据库,我 运行rake db:schema:dump
重新创建了schema.rb
文件。我再次尝试 运行 迁移,但仍然出现相同的错误。
我正在使用 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
它奏效了。
这很奇怪,因为 references
与 sqlite3
一起工作得很好(我通过生成一个虚拟应用程序测试了这个,运行 一个带有 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
应该可以。