🧢

Goとentを使ってますが、初期化データはどうすれば良いでしょうか

2025/03/10に公開

はじめに

こんにちは、Kopherです。
元Javaの開発者がGoにスキルチェンジしたくて個人プロジェクトをGoで作りながら思ったことを投稿しています。

ローカルでアプリを立ち上げるとか、テストで使うために事前にデータがデータベースに登録されていて欲しい場面がありますね、今回、私はアプリをローカル上に立ち上げて挙動を確認したいがデータが先に入っていて欲しいと思いました。Java(Spring)の場合はdata.sqlschema.sqlという名前で作っておけばアプリを立ち上げる時フレームワーク側で実行してくれます。
このいう機能はGo(Gin)、またはentにはないですかね。

軽く調べてみましたが無いようなので解決策考えてみました。

同じくSQLを実行すれば良いのでは

そうですね、Springと同じくアプリが立ち上がる時にSQLを実行すればよいとのことです


import (
    ...
    "database/sql"
    entsql "entgo.io/ent/dialect/sql"
    ...
)

func SetupDB() *ent.Client {
	env := os.Getenv("ENV")
	driver := os.Getenv("DB_DRIVER")
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True",
		os.Getenv("DB_USER"),
		os.Getenv("DB_PASSWORD"),
		os.Getenv("DB_HOST"),
		os.Getenv("DB_PORT"),
		os.Getenv("DB_NAME"),
	)
    // sql 実行のため db instanceを取得しています。
	db, err := sql.Open(driver, dsn)
	if err != nil {
		log.Fatal("Fail connect DB", err)
	}
	drv := entsql.OpenDB(driver, db)
	client := ent.NewClient(ent.Driver(drv))
	ctx := context.Background()

    // TEST の場合のみ動かせる
	if env == "TEST" {
		log.Println("Running migration...")
        // 全部DROPしてから
		executeSQL(db, "config/drop_table.sql")
		err = client.Schema.Create(
			ctx,
			migrate.WithDropIndex(true),
			migrate.WithDropColumn(true),
		)
		if err != nil {
			log.Fatalf("failed creating schema resources: %v", err)
		}
		// データをぶっ込みます
		executeSQL(db, "config/data.sql")
		return client
	}
	if err := client.Schema.Create(ctx); err != nil {
		log.Fatalf("failed creating schema resources: %v", err)
	}
	return client
}

func executeSQL(db *sql.DB, path string) {
	log.Printf("Executing %s ...", path)
	data, err := os.ReadFile(path)
	if err != nil {
		log.Fatalf("failed reading data.sql: %v", err)
	}
	queries := strings.Split(string(data), ";")
	for _, query := range queries {
		query = strings.TrimSpace(query)
		if query == "" {
			continue
		}
		_, err := db.Exec(query)
		if err != nil {
			log.Fatalf("failed executing query %q: %v", query, err)
		}
	}
}

あとはmainで呼び出すだけです!

main.go
func main() {
	config.Initialize()
	client := config.SetupDB()
	r := router.Setup(client)

	r.Run(":8080")
}

最後に

これでいつアプリを起動させても、何回起動させても同じデータが登録されているようになりました。

是非フィードバックお願いします。🙏

entすごく良いです!🌟
https://entgo.io/docs/getting-started/

Discussion