Rails 4 - 从 SQLite 切换到 MySQL - 无法添加外键约束

Rails 4 - Switching from SQLite to MySQL - Cannot add foreign key constraint

长话短说,我开始编写一个无法投入生产的应用程序,但我的老板喜欢它并让我部署它。现在我必须从 SQLite 切换到 MySQL 才能在生产服务器上获取应用程序。

我添加了 gem:gem 'mysql2', '~> 0.3.20',做了 bundle install,并更新了 database.yml:

default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: 
  host: localhost

development:
  <<: *default
  database: umc2_dev

test:
  <<: *default
  database: umc2_test

production:
  <<: *default
  database: umc2
  username: umc2
  password: <%= ENV['PRODUCTION_DATABASE_PASSWORD'] %>

迁移并没有做任何复杂的事情。全部看起来像这样:

create_table :checkins do |t|
  t.string :public_ip
  t.string :private_ip
  t.string :ubermix_version
  t.string :kernel
  t.string :architecture
  t.integer :battery_capacity
  t.integer :system_free
  t.integer :home_free
  t.integer :user_free
  t.references :device, index: true, foreign_key: true
  t.references :location, index: true, foreign_key: true

  t.timestamps null: false
end

当我迁移数据库时,控制台显示:

Mysql2::Error: Can't create table 'umc2.#sql-4e7_10' (errno: 150): \
ALTER TABLE `checkins` ADD CONSTRAINT `fk_rails_ba93b88497`

几个小时以来,我一直在为这个问题苦思冥想。我错过了什么吗?我是否无意中引入了某种存储引擎问题? MySQL 5.7.10 应该默认为 InnoDB 吧?

I例MySql error: 150,必须满足以下条件。

  1. 这两个 table 必须具有相同的引擎,即 ENGINE=InnoDB、ENGINE=MyISAM 等
  2. 两个 table 必须具有相同的字符集。
  3. parent table 中的 Primary Key 列和 child table 中的 Foreign Key 列必须是相同的数据类型。
  4. parent table 中的
  5. Primary Key 列和 child table 中的 Foreign Key 列,如果他们有一个定义的排序规则类型,必须有相同的排序规则 类型。
  6. 如果 Foreign Key table 中已有数据,Foreign Key 列值必须与 Primary Key table Primary Key 列。
  7. 并且childtable不能是临时的table。

希望这会有所帮助。

当我是 运行 SQLite 时,我使用这样的资源生成器:rails g resource checkin device:references。当您将 references 类型传递给生成器时,它会自动将 index: true, foreign_key: true 附加到迁移文件中的适当行。父 table 必须存在才能使用 MySQL 创建引用 table,但如果父 table 首先不存在,SQLite 不会抱怨。

我不得不编写额外的迁移,将引用列添加到签入 table。我认为您可以删除 foreign_key: true 位而不影响 ActiveRecord 关系,但我不确定这是否是首选解决方案。