LoginSignup
0
0

More than 1 year has passed since last update.

gorm with PostgreSQL で Primary Key / ID を UUIDv4 にするには ( Docker 対応 )

Posted at

Motivation

  • できるだけ gorm 標準の gorm.Model に準拠させた形にして、gorm の恩恵を受けたい
import (
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

type Product struct {
	gorm.Model
	Code  string
	Price uint
}
// → このままだと PK が uint / auto_increment フィールドになる

結論

以下のサンプルコードをご覧ください。

type UUIDBaseModel struct {
	// UUID が主キーになり、UUID は Postgres が勝手に生成する
	ID        string `gorm:"primaryKey;size:255;default:uuid_generate_v4()"`
	CreatedAt time.Time
	UpdatedAt time.Time
	DeletedAt gorm.DeletedAt `gorm:"index"`
}

type Product struct {
	// UUIDBaseModel を含む struct は全て UUID が主キーになる
	UUIDBaseModel
	Code  string
	Price uint
}

func migrate() {
	dsn := "host=localhost user=user password=password dbname=dbname port=5432 sslmode=disable TimeZone=Asia/Tokyo"
	db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
		if err != nil {
			panic(err)
		}

	// 追加: PostgreSQL に拡張機能 "uuid-ossp" を追加する
	db.Exec(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp";`)

	// マイグレーションを行なう
	err = db.AutoMigrate(&Product{})
	if err != nil {
		panic(err)
	}
}

ポイントは以下の3点です。

  • マイグレーションを行なう前に、SQL句 CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; を実行する
    go ではなく実際に SQL のコンソールに入って実行しても構いませんが、go で実行することをおすすめします。

    db.Exec(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp";`)
    
  • UUID が主キーになるようなモデルをつくる
    この構造体が埋め込まれた構造体はすべてで、Primary Key が UUID になります。

    type UUIDBaseModel struct {
      // UUID が主キーになり、UUID は Postgres が勝手に生成する
      ID        string `gorm:"primaryKey;size:255;default:uuid_generate_v4()"`
      CreatedAt time.Time
      UpdatedAt time.Time
      DeletedAt gorm.DeletedAt `gorm:"index"`
    }
    
  • 実際にマイグレートするモデルの構造体にはすべて UUIDBaseModel を含める

    type Product struct {
      // UUIDBaseModel を含む struct は全て UUID が主キーになる
      UUIDBaseModel
      Code  string
      Price uint
    }
    

Docker の postgres 公式イメージを使用している場合

マイグレーションを行なう前に、SQL句 CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; を実行する方法以外に、環境変数で拡張機能 uuid-ossp を追加することができます。
これにより、 db.Exec(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp";`) の追記が不要になります。
環境変数 POSTGRES_EXTENSIONS=uuid-ossp を追記して下さい。

Dockerfile
FROM postgres:9.6.23
USER root

# 以下を追記
ENV POSTGRES_EXTENSIONS=uuid-ossp
docker-compose.yml
services:
  postgres:
    environment:
      # 以下を追記
      POSTGRES_EXTENSIONS: uuid-ossp

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0