6783


MySQL5.6から NOT NULL制約 を付けているのに、DEFAULT値が設定されていない場合は、  
INSERT等が出来なくなってしまっています。

オプションで変更することも可能なのですが……。  
既に出来上がっているデータベースの構造から全テーブル、全カラムを確認して、  
問題解決するための migration(差分) を用意するには、どうしたらいいでしょうか。


CC BY-SA 3.0
2015-02-19T12:16:56.720
6782
2015-02-25T03:56:56.303
8335
question
ruby-on-rails mysql
MySQL5.6対応で「doesn't have a default value」となるエラーの差分migrationの動的生成方法は？


全てのテーブル名は、ActiveRecord::Base.connection.tablesで取得できます。  
このテーブル名１つ１つを、classifyして、constantizeすればクラス処理できます。

クラス毎に、.columnsで全カラムを取得して、処理していきます。

  1. column.name が class.primary_key だったら 次カラムへスキップ。  
※ おそらく id であり PRIMARY_KEY がついているはずです。

  2. column.null が true だったら次カラムへスキップ
  3. column.default が nil でなければ次カラムへスキップ
  4. column.cast_type.typeを判定して、デフォルト値を決定する。
  5. change_column_default文を組み立てて出力する。

そういう需要で作ったサンプルコードも提示しておきます。

[code]

    default_values = {
        integer: 0, text: nil, string: '', boolean: false,
        datetime: '0000-00-00 00:00:00',
        decimal: 0, float: 0.0
    }
    tables = ActiveRecord::Base.connection.tables
    klasses = tables.map(&:classify).map do |class_name|
      begin
        class_name.constantize
      rescue NameError
      end
    end
    klasses.uniq!.compact!
    klasses.each do |klass|
      pkey = klass.primary_key
      klass.columns.each do |column|
        type, null, default = column.cast_type.type, column.null, column.default
        next if column.name == pkey
        next if null == true or not default.nil?
        raise "ERROR: #{klass.name}.#{column.name} with #{type} not support yet." unless default_values.has_key?(type.to_sym)
        next if (value = default_values[type]).nil?
        puts "change_column_default :#{klass.table_name}, :#{column.name}, #{value.inspect}"
      end
    end
    
[/code]


CC BY-SA 3.0
2015-02-19T12:16:56.720
6783
2015-02-25T03:56:56.303
2015-02-25T03:56:56.303
8335
8335
6782
answer