使用rake db:migrate命令和mysql在Rails中创建表的PRIMARY KEY问题

Aer*_*ll1 23 mysql rake ruby-on-rails primary-key dbmigrate

我的版本的rails是4.0.0,我的mysql版本是Ver 14.14 Distrib 5.7.9,适用于Win64(x86_64).我正在运行一个旧版本的rails,因为我正在根据我之前的问题在这里与mysql发生冲突.(查看Kalelc批准的回答我的追索权)

跑步

rake db:migrate 
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

==  CreateUsers: migrating ====================================================
-- create_table(:users)
rake aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead: CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `first_name` varchar(25), `last_name` varchar(50), `email` varchar(255) DEFAULT '' NOT NULL, `password` varchar(40), `created_at` datetime, `updated_at` datetime) ENGINE=InnoDBC:/Users/Lizanne/Documents/Code/Sites/simple_cms/db/migrate/20151116154434_create_users.rb:3:in `up'
C:in `migrate'
ActiveRecord::StatementInvalid: Mysql2::Error: All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead: CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `first_name` varchar(25), `last_name` varchar(50), `email` varchar(255) DEFAULT '' NOT NULL, `password` varchar(40), `created_at` datetime, `updated_at` datetime) ENGINE=InnoDB
C:/Users/Lizanne/Documents/Code/Sites/simple_cms/db/migrate/20151116154434_create_users.rb:3:in `up'
C:in `migrate'
Mysql2::Error: All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead
C:/Users/Lizanne/Documents/Code/Sites/simple_cms/db/migrate/20151116154434_create_users.rb:3:in `up'
C:in `migrate'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
Run Code Online (Sandbox Code Playgroud)

我的代码中没有将任何值设置为NULL,这是代码

Class CreateUsers < ActiveRecord::Migration

  def up
    create_table :users do |t| 
      t.column "first_name", :string, :limit => 25 
      t.string "last_name", :limit => 50
      t.string "email", :default => "", :null => false 
      t.string "password", :limit => 40
      t.timestamps
    end
  end

  def down
    drop_table :users
  end
end
Run Code Online (Sandbox Code Playgroud)

此代码完全如我正在遵循的教程中所示.我还在堆栈溢出中调查了其他类似的问题,并遵循给出的建议.我按照建议尝试了猴子补丁

# lib/patches/abastract_mysql_adapter.rb
class ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
  NATIVE_DATABASE_TYPES[:primary_key] = "int(11) auto_increment PRIMARY KEY"
end
Run Code Online (Sandbox Code Playgroud)

我将此文件插入到我在simple_cms应用程序的lib中创建的名为patches的文件夹中.我按照同一个猴子补丁中的建议将文件保存为"abstract_mysql_adapter.rb".我已经使用以下内容更新了simple_cms应用程序的environment.rb

require File.expand_path('../../lib/patches/abstract_mysql_adapter.rb', __FILE__)
Run Code Online (Sandbox Code Playgroud)

如果我然后运行rake db:migrate命令

rake aborted!
LoadError: cannot load such file -- C:/Users/Lizanne/Documents/Code/Sites/simple_cms/lib/patches/abstract_mysql_adapter.rb
C:/Users/Lizanne/Documents/Code/Sites/simple_cms/config/environment.rb:3:in `<top (required)>'
Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)
Run Code Online (Sandbox Code Playgroud)

C:/Users/Lizanne/Documents/Code/Sites/simple_cms/lib/patches/abstract_mysql_adapter.rb绝对是猴子补丁的路径.我把补丁放在了错误的地方吗?我在这里做错了什么,在这个问题上摸不着头脑?如果对一些人来说这是显而易见的,我会道歉,但是在经过很长时间的禁欲之后我又回到了编码状态,我无法理解这个问题.非常感谢您的帮助:)

小智 73

我最近也面临同样的问题.

MySQL 5.7不再支持主键的空默认值.

通过覆盖MySql中主键的Native默认值,您可以解决您的问题.

在config/initializers/abstract_mysql_adapter.rb中:

class ActiveRecord::ConnectionAdapters::MysqlAdapter
  NATIVE_DATABASE_TYPES[:primary_key] = "int(11) auto_increment PRIMARY KEY"
end
Run Code Online (Sandbox Code Playgroud)

对于mysql2,它应该是config/initializers/abstract_mysql2_adapter.rb:

class ActiveRecord::ConnectionAdapters::Mysql2Adapter
  NATIVE_DATABASE_TYPES[:primary_key] = "int(11) auto_increment PRIMARY KEY"
end
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的答案.不要看它的低质量. (6认同)

And*_*Day 12

上面的解决方案没有运气(我的环境:Rails 3.0.20,MySQL 5.7.13,Ruby 1.9.3p551).能够通过覆盖ActiveRecord::ConnectionAdapters::ColumnDefinition课程来绕过它.见下文:

class ActiveRecord::ConnectionAdapters::ColumnDefinition
  def sql_type
    type.to_sym == :primary_key ? 'int(11) auto_increment PRIMARY KEY' : base.type_to_sql(type.to_sym, limit, precision, scale) rescue type
  end 
end
Run Code Online (Sandbox Code Playgroud)

在config/initializers/column_definition.rb中存储


H6.*_*H6. 2

从 MySQL 5.7.3 开始,声明为 NULL 的主键会产生错误:

PRIMARY KEY 中的列必须为 NOT NULL,但如果显式声明为 NULL,则不会产生错误。现在出现错误。例如,诸如 CREATE TABLE t (i INT NULL PRIMARY KEY) 之类的语句会被拒绝。对于类似的 ALTER TABLE 语句也会发生同样的情况。(错误#13995622、错误#66987、错误#15967545、错误#16545198)

但是create_table在你的 Rails 版本中仍然需要一个DEFAULTorNULL来表示PRIMARY KEY. 我已经通过更新到较新的 Rails 版本解决了该问题。