🚅
Gorm(1.0)でprimary keyが設定されなくてハマった話

myuon

myuon

2022年5月11日
gogorm

# 事例

ある時、特定のテーブルでprimary keyが設定されていないことに気がつきました。対象となったテーブルは2つだけで、他のテーブルでは正しく設定されていました。 この事象が発生した2テーブルはcomposite primary keyを設定しようとしていたため、何か複合キーに関するgormのバグを踏んだのだろうか?などと思いながら調査をしていましたが原因がしばらくわからず苦労したという話です。

結論から言えば、これは以下の2つの事象が重なって起きたものです。

# 1: Gorm1.x系のプライマリーキーの指定はprimaryKeyではなくprimary_key

そのままですが、primary keyの指定をするのは1系はsnake_caseで、2系ではcamelCaseになりました。 私は2系でcamelCaseになったという情報を得ていたのですが、それを勘違いして1.0でもprimaryKeyと書いていました。このためprimary keyの設定は一切されていないことになっていました。 (特にこの間違いがあっても警告などは出ません)

# 2: プライマリーキーの指定がない時、Idがあると自動でプライマリーキーになる

プライマリーキーに関する指定がなく、idという名前のフィールドがある場合はgormは自動的にidをプライマリーキーに指定します。 このため多くのケースではプライマリーキーの指定がなくとも問題がなく、発覚が遅れました

# 対応策

対応についても意外と面倒です。Gormはプライマリーキーの変更を行なってもAutoMigrateでは変更を行いません。そのため、プライマリーキーを貼り直すためにはSQLを直接発行するなどの作業が必要です。

db.Conn.Exec("ALTER TABLE table ADD CONSTRAINT PRIMARY KEY (user_id, other_id);")

などを実行することでprimary keyを設定できます。 (ちなみにこのクエリはMySQL上で実行されることを想定しているものですが、冪等ではないです。PostgreSQLだとALTER TABLEにIF NOT EXISTSとかけるみたいなのでそうなって欲しいなと思いました)

# まとめ

ドキュメントをちゃんと読もう。