gorm + pg + inet

最近 SQL 有儲存 IP 的需求,使用的是 cockroachDB,由於 protocol 跟 postgreSQL 一樣,所以先從 PG 著手,會發現有 inet 跟 cidr 可以使用,而在 golang 裡要如何使用 inet 與 cidr 呢?這個留到後面再煩惱,先把連線建立起來。

那就來試試吧,先啟動一個 CRDB,為了方便沒有使用憑證

$ cockroach start-single-node \ --insecure \ --listen-addr=localhost:26257 \ --http-addr=localhost:8083

啟動後可以看到連線資訊 postgresql:... 記起來等一下連線可以使用

接著寫個小程式連線,使用 gorm 連線,可以在 gorm 的官網找到範例程式

package main import ( "log" "gorm.io/driver/postgres" "gorm.io/gorm" ) func main() { dsn := "postgresql://localhost:26257/defaultdb?sslmode=disable&user=root" _, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { log.Fatal(err) } }

接著如何使 golang 與 inet 產生連結?
尋找 pgx 會發現可以直接使用 netip.Addr,這真是太棒了,馬上來試試!

建立一個 ip 的 struct

type IP struct {
	gorm.Model
	IP     netip.Addr
	Answer string
}

接著建立 migration

var Migrations = []*gormigrate.Migration{ { ID: "20240515IP", Migrate: func(db *gorm.DB) error { return db.AutoMigrate(IP{}) }, Rollback: func(db *gorm.DB) error { return db.Migrator().DropTable(IP{}) }, }, } func main() { // ... m := gormigrate.New(db, gormigrate.DefaultOptions, Migrations) if err := m.Migrate(); err != nil { log.Fatal(err) } }

會遇到錯誤

[error] invalid field found for struct main.IP's field IP: define a valid foreign key for relations or implement the Valuer/Scanner interface