1 回答

TA貢獻1802條經驗 獲得超4個贊
以防萬一您不知道,jsonb[]這是一個PostgreSQL 數組類型,其元素類型為jsonb. 它不是“json 數組”類型。
如果要將 JSON 數據存儲在列中,無論您希望該數據包含標量、對象還是數組JSON 值,都應使用json/類型。jsonb
因此,除非您選擇 PostgreSQL 數組類型時考慮了一些特定的用例,否則最好將列的類型從更改jsonb[]為jsonb.
如果您不能或不想更改列類型,那么您仍然可以在 SELECT 查詢中將 PostgreSQL 數組轉換為 JSON 數組,然后,在您的自定義 Gosql.Scanner實現中,用于json.Unmarshal解碼數據庫數據.
SELECT to_jsonb(advance_payment) FROM booking_settings WHERE hotel_id = $1
-- or
SELECT array_to_json(advance_payment)::jsonb FROM booking_settings WHERE hotel_id = $1
type advanceAndRoomPaymentList []advanceAndRoomPayment
func (ls *advanceAndRoomPaymentList) Scan(src any) error {
var data []byte
switch v := src.(type) {
case string:
data = []byte(v)
case []byte:
data = v
}
return json.Unmarshal(data, ls)
}
如果您有許多查詢引用 PostgreSQL 數組列并且您不想更新每個查詢以進行轉換,您可以自己解析 PostgreSQL 數組然后解組各個元素,或者您可以將這項工作委托給某些人第 3 方實施。
這是一個未經測試的示例,使用pq.GenericArray:
// I haven't tested the following but I'd assume it ought to work,
// if not, then perhaps maybe small tweaks are needed here and there...
type advanceAndRoomPaymentList []advanceAndRoomPayment
func (ls *advanceAndRoomPaymentList) Scan(src any) error {
return pq.GenericArray{ls}.Scan(src)
}
// implement Scanner for the element type of the slice
func (a *advanceAndRoomPayment) Scan(src any) error {
var data []byte
switch v := src.(type) {
case string:
data = []byte(v)
case []byte:
data = v
}
return json.Unmarshal(data, a)
}
如果您想自己解析 PostgreSQL 數組,那么您需要了解用于表示此類數組的語法。您可以在此處找到相關文檔:
數組值的外部文本表示由根據數組元素類型的 I/O 轉換規則解釋的項以及指示數組結構的裝飾組成。裝飾由圍繞數組值的大括號({ 和 })加上相鄰項之間的定界符組成。分隔符通常是逗號 (,),但也可以是其他字符:它由數組元素類型的 typdelim 設置決定。在 PostgreSQL 發行版提供的標準數據類型中,除了 type box 使用分號(;)外,都使用逗號。
因此,例如,如果您有包含一個 json 對象、一個 json 數組、一個 json 字符串和一個 json 布爾的 pg 數組,并且您選擇了它,那么將傳遞給sql.Scanner實現的數組表示將看起來像:
{"{\"foo\": \"bar\"}","[\"foo\", \"bar\"]","\"foo bar\"",true}
- 1 回答
- 0 關注
- 287 瀏覽
添加回答
舉報