はじめに
Postgresから取得したjson型の配列をGoで受け取る必要がありましたため
手順などまとめました。
結論
- postgresに登録するjson配列の型はjson型またはjsonb型を指定する
- Go側でデータ取得する際、byteスライスで受取。その後json.Unmarshalを行う
確認した環境
DB: Postgresql:16.2-alpine3.19(Docker)
Go: v1.23.6
確認手順
DBデータ
json型で確認を行っていますが、jsonb型でも同様です。
- 以下のカラムとデータを作成
カラム名: users
型: json
データ
'[{"user_id": 1, "user_name": "test1", "height": 170.5}, {"user_id": 2, "user_name": "test2", "height": 165.0}, {"user_id": 3, "user_name": "test3", "height": 180.2}]'
Go側の処理
- DBよりデータ取得(この際usersは[]byteで受け取る)
- json.Unmarshalで構造体へバインドする
type User struct {
ID int64 `json:"user_id"`
Name string `json:"user_name"`
Height float64 `json:"height"`
}
type Row struct {
Hoge string
Users []byte
}
// 1.DBよりデータ取得
// 戻り値rowは、上記Row型の想定
row := FetchUserWithHoge()
// 2.json.Unmarshalで構造体へバインドする
var users []User
if err := json.Unmarshal(row.Users, &users); err != nil {
return err
}
個人的にハマったポイント
- DBへのカラム登録時、初めは、json[]型でデータを登録していたため、うまくバインドができなかった
- Unmarshal時、指定した構造体にjsonタグとは違うタグを指定していた
(ORM用のタグを指定していたため、うまくバインドができていませんでした。)
さいごに
アンチパターンと言われるjson型を取り扱う機会がいままでなかったため、
調べた内容を記録として記事にさせていただきました。