🔨
【Rails】Ridgepole 使用時に主キーを変更すると起こるエラー
はじめに
RidgepoleでRailsのDBスキーマ管理をしている際に出会った[ERROR] PG::DuplicateColumn: ERROR: column "***" of relation "***" already exists
のエラーについてまとめます。
エラー概要
下のようにprimary_keyがcodeカラムになるようにSchemafileを記述していました。
Schemafile
create_table "companies", force: :cascade, id: false do |t|
t.string "code", primary_key: true, comment: "企業コード"
t.string "name", comment: "企業名"
end
2回目以降のapply時に下のような[WARNING]と[ERROR]が発生していました。
$ ridgepole --config config/database.yml --apply --file db/Schemafile # 1回目
Apply `db/Schemafile`
-- create_table("companies", {:id=>false})
-> 0.0058s
$ ridgepole --config config/database.yml --apply --file db/Schemafile # 2回目
Apply `db/Schemafile`
[WARNING] Primary key definition of `companies` differ but `allow_pk_change` option is false
from: {:id=>{:type=>:string, :comment=>"企業コード"}}
to: {:id=>false}
[WARNING] PostgreSQL doesn't support adding a new column except for the last position. companies.code will be added to the last.
-- add_column("companies", "code", :string, {:primary_key=>true, :comment=>"企業コード"})
[ERROR] PG::DuplicateColumn: ERROR: column "code" of relation "companies" already exists
* 1: add_column("companies", "code", :string, **{:primary_key=>true, :comment=>"企業コード"})
/usr/local/bundle/gems/activerecord-7.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:48:in `exec'
警告とエラー内容を見てみても、
- [WARNING] Primary key definition of
companies
differ butallow_pk_change
option is false...- [WARNING] PostgreSQL doesn't support adding a new column except for the last position. companies.code will be added to the last.
- [ERROR] PG::DuplicateColumn: ERROR: column "code" of relation "companies" already exists
何が間違っているのかわかりませんねー
本来は、変更をしていない場合2回目以降のapplyにはNo change
と表示されるはずです。
解決方法
下のようにSchemafileを書き換えました。
Schemafile
create_table "companies", force: :cascade, primary_key: "code", id: { type: :string, comment: "企業コード" } do |t|
t.string "name", comment: "企業名"
end
id: false
の代わりにprimary_key:
を指定するように変更しました。
修正後に再度applyを実行すると、
$ ridgepole --config config/database.yml --apply --file db/Schemafile
Apply `db/Schemafile`
No change
primary_keyをid以外に設定しても、2回目以降のapply時にエラーが発生しなくなりました。
Discussion