ワーパパエンジニアの学び手帳

ワーパパエンジニアの業務外での学びとかガジェットネタとか

PostgreSQLのALTER TABLEに苦戦

PlayframeworkではDDLを予め用意しておくことでアプリケーションの起動時にDDLを実行してテーブルを自動生成してくれます(evolutions)。
Java版だとModelからDDLを自動生成してくれますが、Scala版だとDDLは自分で書く必要があります(という認識)。

自作アプリケーション作成時に、ローカルではH2、本番(Heroku)ではPostgreSQLを使用しています。
ところが、ローカルでは実行できていたDDLがHerokuではコケるという事象が。
PostgreSQLのエラーログがいまいちわかりづらくてなかなか原因が把握しづらかったのですが、どうやら以下の通りらしい。

H2とPostgreSQLではALTER TABLEの文法が異なる

今回コケたのはALTER TABLE文で、カラムの型変更をしようとしてました。

/* H2 */
alter table TABLE1 alter column COLUMN1 (DATATYPE); 
/* PostgreSQL */
alter table TABLE1 alter column COLUMN1 [SET DATA] TYPE (DATATYPE);

(DATATYPE)は変更後の型、[]内の有無は任意です。

さらに、今回カラムの型変更と同時にデフォルト値の設定をしようとしたのですが、H2では1文で実行できる一方、PostgreSQLでは2文に分けないと実行できないようです。

/* H2 */
alter table TABLE1 alter column COLUMN1 TIMESTAMP SET DEFAULT CURRENT_TIMESTAMP;
/* PostgreSQL */
alter table TABLE1 alter column COLUMN1 [SET DATA] TYPE TIMESTAMP;
alter table TABLE1 alter column COLUMN1 SET DEFAULT CURRENT_TIMESTAMP;

この例ではTIMESTAMP型に変更し、デフォルト値に実行時のTIMESTAMPを指定しています。

データベースによりSQLの文法が変わってくるので、環境間で異なるデータベースを使うのは極力避けましょうってことですね。

参考

[H2] http://www.h2database.com/html/grammar.html#alter_table_add
[PostgreSQL] https://www.postgresql.jp/document/9.4/html/sql-altertable.html