Rails 3.2.6 と Mysql 6.0.9 を使用しています (ただし、MySQL 5.2.25 でもまったく同じエラーが発生します)。
新しいデータベース ( rake db:create
) を作成し、スキーマ ( rake schema:load
) をロードしようとすると、次のエラーが発生します。
Mysql2::Error: Specified key was too long; max key length is 767 bytes: CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
何時間もの調査の後、私はこれらの解決策を見つけました:
1. MySQL 変数 innodb_large_prefix を true (または ON) に変更します。
これはうまくいきませんでした。Linux サーバー、Mac、さらには Windows でも試してみましたが、うまくいきません。
2. モンキーパッチ ActiveRecord::SchemaMigration.create_table
列の長さを 255 にする必要はありませんversion
(UTF-8 の場合、4*255 = 1020 バイトかかり、キーの MySQL 制限である 767 バイトを超えます)。UTF-8 である必要もありませんが、DB 内の他のすべてのテーブルは UTF-8 であり、utf8_czech_ci をデフォルトの照合順序に設定しました。
実際に schema_migrations テーブルを作成するメソッドは次のようになります。
def self.create_table
unless connection.table_exists?(table_name)
connection.create_table(table_name, :id => false) do |t|
t.column :version, :string, :null => false
end
connection.add_index table_name, :version, :unique => true, :name => index_name
end
end
Github rails/railsでファイル全体を読むことができます
:limit => 100
そのため、ステートメントに追加しようとしましt.column
たが、このソリューションでも成功しませんでした。問題は、オリジナルが既に配置されている場合、このパッチをロードできないことです。つまり、私のパッチはActiveRecord::SchemaMigrationの前に読み込まれるため、上書きされます。
これを入れるとconfig/initializers/patches/schema_migration.rb
:
require 'active_record/scoping/default'
require 'active_record/scoping/named'
require 'active_record/base'
module ActiveRecord
class SchemaMigration < ActiveRecord::Base
def self.create_table
unless connection.table_exists?(table_name)
connection.create_table(table_name, :id => false) do |t|
t.column :version, :string, :null => false, :limit => 100
end
connection.add_index table_name, :version, :unique => true, :name => index_name
end
end
end
end
正常にロードされますが、元の ActiveRecord::SchemaMigration がロードされると上書きされます。
ActiveSupport.on_load(:active_record) を台無しにしようとしましたが、それもうまくいかないようです。
元の ActiveRecord::SchemaMigration が配置された後にこのファイルをロードして、このパッチを機能させる方法はありますか?
何か提案はありますか?この質問の意味がわからない場合は、どの部分でも明確にすることができます。私に聞いてください。私はこれにあまりにも長い間立ち往生してきました。