📖
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.NullStringtype 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