📖
PostgresとGolangのデータ型対応表
PostgreSQLとGoのデータ型対応表
PostgreSQLデータ型 | Goのデータ型 (database/sql での推奨) | 備考 |
---|---|---|
SMALLINT |
int16 |
|
INTEGER |
int32 または int
|
int はシステムに依存するため、明示的なint32 が良い場合も。 |
BIGINT |
int64 |
|
SERIAL |
int32 または int
|
自動インクリメント。Goではint で受け取る。 |
BIGSERIAL |
int64 |
自動インクリメント。Goではint64 で受け取る。 |
REAL |
float32 |
精度に注意。float64 にスキャンすると精度問題が発生する可能性あり。 |
DOUBLE PRECISION |
float64 |
|
NUMERIC , DECIMAL
|
float64 または string または *pgtype.Numeric (pgxの場合) |
厳密な精度が必要な場合はstring で受け取り、独自で計算するか、専用の型(pgtype.Numeric など)を使用するのが推奨されます。float64 では丸め誤差が生じる可能性があります。 |
BOOLEAN |
bool |
|
TEXT , VARCHAR , CHAR
|
string |
|
BYTEA |
[]byte |
バイナリデータ。 |
DATE |
time.Time |
日付のみ。 |
TIME |
time.Time |
時刻のみ。 |
TIMESTAMP , TIMESTAMPTZ
|
time.Time |
タイムゾーン情報を持つかどうかで、扱いが少し異なる場合がありますが、Goではtime.Time で対応できます。 |
JSON , JSONB
|
[]byte または 構造体 (encoding/json でMarshal/Unmarshal) |
[]byte でJSON文字列として取得し、json.Unmarshal でGoの構造体に変換するのが一般的です。json.RawMessage も利用可能です。 |
UUID |
string または [16]byte (pgxの場合) |
文字列で扱うのが一般的ですが、pgx などの一部ドライバでは専用の型も提供しています。 |
INET , CIDR
|
net.IP または netip.Addr (Go 1.18以降) |
IPアドレス。 |
ARRAY (例: INTEGER[] ) |
[]int32 または pq.Int64Array (pqの場合), []string など (要素の型による) |
database/sql 標準では配列型を直接スキャンするのが難しい場合があります。ドライバ(pq のpq.Int64Array など)が提供するカスタム型を使用するか、JSONとして扱う方法が考えられます。pgx では配列型を直接サポートしています。 |
XML |
string または []byte
|
XML文字列として取得。 |
NULLABLE な型 |
sql.NullString , sql.NullInt64 , sql.NullBool , sql.NullTime など または ポインタ型 (*string , *int など) |
NULLの可能性があるカラムは、database/sql が提供するsql.Null 系の型を使用するか、ポインタ型で受け取ることでNULLを表現できます。 |
補足事項
-
database/sql
パッケージのNull許容型:
PostgreSQLでNULLが許容されるカラムをGoで扱う場合、database/sql
パッケージのsql.NullString
,sql.NullInt64
,sql.NullBool
,sql.NullFloat64
,sql.NullTime
などの型を使用することが推奨されます。これらの型は、値とそれがNULLであるかどうかの情報(Valid
フィールド)を保持します。
例:sql.NullString
type User struct { ID int Name sql.NullString // NULLを許容するTEXT型カラム }
あるいは、Goのポインタ型を使用することもできます。
type User struct { ID int Name *string // NULLを許容するTEXT型カラム }
-
pgx
ドライバの使用:github.com/jackc/pgx
は、database/sql
インターフェースを実装していますが、よりPostgreSQLに特化した豊富な型マッピングを提供しています。例えば、pgtype
パッケージを使用することで、より正確な型変換が可能になります。
特にNUMERIC
やDECIMAL
のような厳密な精度が求められる数値型、UUID
、配列型などで、pgx
の提供する型を使用すると便利です。 -
JSON/JSONBの扱い:
JSON
やJSONB
は、Goの構造体と簡単にマッピングできます。import ( "encoding/json" // ... ) type MyData struct { Key1 string `json:"key1"` Key2 int `json:"key2"` } type MyTable struct { ID int Data json.RawMessage // または []byte } // 取得時 var t MyTable // ... db.QueryRow(...).Scan(&t.ID, &t.Data) var d MyData err := json.Unmarshal(t.Data, &d) // 保存時 myData := MyData{Key1: "value", Key2: 123} jsonBytes, err := json.Marshal(myData) // ... db.Exec("INSERT INTO my_table (data) VALUES ($1)", jsonBytes)
-
カスタム型:
上記にないPostgreSQLの特殊なデータ型(例えば、幾何学データ型など)や、より複雑な変換が必要な場合は、Goのsql.Scanner
およびdriver.Valuer
インターフェースを実装することで、独自のGo型を定義し、データベースの型とマッピングすることができます。
Discussion