概要
GORMではUpsertの機能があり、コンフリクト時の判定キーや更新対象のカラムを指定することができます。
今回はGenを使用して実装したのですが、GenのドキュメントUpsert / On Conflictを確認すると、「UpdateAll」を指定すれば主キーをコンフリクト判定に使用してコンフリクト時に主キー以外の項目を更新してくれるそうですので、試してみました。なお、GORMのドキュメントUpsert / On Conflictにも同様の機能が記載あるので、Genを使わなくてもほぼ同様の実装で行えると思われます。
前提
- 使用したgorm.io/genのバージョンは
v0.3.27になります。 - 使用したDBはPostgreSQLです。
実装サンプル
モデルとして、以下のような定義を用意します。
type SampleSetting struct {
ID string `gorm:"column:id;primaryKey" json:"id"`
Name string `gorm:"column:name;not null" json:"name"`
OwnerUserAccountID string `gorm:"column:owner_user_account_id;not null" json:"owner_user_account_id"`
ParentSettingID *string `gorm:"column:parent_setting_id" json:"parent_setting_id"`
DisplayOrder *int32 `gorm:"column:display_order" json:"display_order"`
Description *string `gorm:"column:description" json:"description"`
}
このモデルを使用してUpsert対象のオブジェクトを作成し、UpdateAllを指定して更新をかけます。
func RegisterSampleSettings(ctx context.Context, sampleSettings []*db_model.SamlpleSetting) error {
s := query.SamlpleSetting
return s.WithContext(ctx).Clauses(clause.OnConflict{
UpdateAll: true,
}).Create(sampleSettings...)
}