RubyのsequelというORMライブラリがあります。
細かい使い方はQiitaにいくつか記事があるのでそちらを参照するとして、今回はMySQLで以下のような列にcharacter setが指定してあるDDLを発行させる方法のメモ書きです。
確認したバージョンは sequel 4.2.0
, adapterにmysql2 0.3.13
です。
create table example1(
id bigint not null,
url varchar(255) character set ascii not null,
constraint pk primary key (id)
) engine=InnoDB, default character set='utf8mb4';
先にMySQLにテーブルを作ってdumpをしても、認識してくれません(´・ω・`)
bundle exec sequel -e development ./config/database.yml -d
Sequel.migration do
change do
create_table(:example1) do
primary_key :id, :type=>Bignum
String :url, :size=>255, :null=>false
end
end
end
bundle exec sequel -e development ./config/database.yml -D
Sequel.migration do
change do
create_table(:example1) do
primary_key :id, :type=>"bigint(20)"
column :url, "varchar(255)", :null=>false
end
end
end
これを実行しても、列に指定してあるcharacter setがおちてしまいます。あと create table のオプションに InnoDB, utf8が出ています。utf8mb4 を指定したのに・・。このへんは Sequel::MySQL.default_engine
Sequel::MySQL.default_charset
Sequel::MySQL.default_collate
あたりで設定するみたいです。今回はcreate_tableの時に指定してみます。
mysql> show create table example1 \G;
*************************** 1. row ***************************
Table: example1
Create Table: CREATE TABLE `example1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`url` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
ERROR:
No query specified
というわけで、以下のように修正してみました。まず、create_table する時に明示的に engine と charset を指定しました。 また列定義で明示的に character set asciiを追加しました。オマケでchangeからup/downに変更しています。
Sequel.migration do
up do
create_table(:example1, :engine => 'InnoDB', :charset=>'utf8mb4') do
primary_key :id, :type=>"bigint(20)"
column :url, "varchar(255) character set ascii", :null=>false
end
end
down do
drop_table(:example1)
end
end
↑を実行すると、↓のような結果にできました。
mysql> show create table example1 \G;
*************************** 1. row ***************************
Table: example1
Create Table: CREATE TABLE `example1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`url` varchar(255) CHARACTER SET ascii NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
ERROR:
No query specified
ただし、この方法だとRDB間の差異は吸収できません。String :url, :size=>255, :charset=>'ascii'
と書けると嬉しいんですけどね・・。知ってる人いたら教えてください。