rublogのPostgreSQL対応

気になっていたrublogのPostgreSQL対応にチャレンジしました。目論見では、ActiveRecordで相違が吸収されるので何もしないでOKのハズだったのですが、Migrateでいくつかの問題がありました。

  • add_columnで:null=falseを指定するとエラー
  • :integer :limit=>11のようにサイズを指定するとエラー
  • add_indexで名前重複エラー
  • create table :option=>{}にdefaultcharsetの指定でエラー

(1):null=>falseでのエラーはを指定するとエラー。PostgreSQLの場合default句の指定はinsert時のみ有効ということなのでnot nullのカラムを追加する場合、

add_column :table_name, :column_name, :integer, :default=>0
execute "update table_name set column_name = 0;"
execute "alter table table_name alter column column_name set not null"

のように手順を踏む必要があるようです。三番目のalter ...は

change_column :table_name, :column_name :integer :null=>false

で対応できるかと思ったのですが、エラーにはならないものの変更はできませんでした。

(2)PostgreSQLの場合、integerタイプにサイズ指定はできません。これはもう如何ともしがたい。ものぐさな僕はサイズ指定なしのintegerで書いていたのでこの部分には引っかからなかったのですが、Rubricks本体に :integer :limit=>xxの箇所があるのでこれは手修正しました。Migrateの抽象表現ではsmallint,bigintなどはないようですから一律integerとするしかないのかな?

(3)create_table時のoptionでdefault charset=utf8の指定不可。レンタルサーバのMySQL環境がLatinだったのでこのオプションを付けていたのですがPostgreSQLの場合、create tableにこういうオプションがないので当然エラー。これははずすしかありません。database.ymlのencoding=utf8で大丈夫な筈なのですが僕の環境ではうまくいっていなかったような...(この部分は調査するのをすっかり忘れていました。)

(4)MySQLではインデックス名はテーブル単位ですがpostgreSQLではデータベースで一意にする必要があって重複はエラーとなります。Rubricks本体のadd_indexにいくつか名前が重複するものがあったのでこれは手修正。

その他発覚したバグ。rublogで使用しているテーブルはMyISAMなくせに無意味に外部参照制約をつけていたので(おバカ)これは外しました。また、当然アンインストール時のdrop順も制限されるのでここも修正する必要ががありました。ここらあたりコードに丁寧さが欠けることが浮き彫りですね。

やっぱり、色々あります。こうなると一つの定義ファイルで双方をカバーするのは難しいのかもしれません。alter構文やオプション系はで逃げようにもその中の構文が違えばやっぱりダメな訳だし最初からターゲットDBを絞り込んだパッケージを作成するほうがすっきりする気がします。まっ、いづれにせよMySQLで足場をしっかり固めてからですね。

rubricks-0.5.4 / postgresql 8.0.1 / postgres0.7.1でテストしました。

この記事のトラックバックURL:

http://hippos-lab.com/blog/trackback/98

Comments