亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將 jsonb 對象從 Postgresql 掃描到 golang 結構

如何將 jsonb 對象從 Postgresql 掃描到 golang 結構

Go
手掌心 2023-02-06 19:41:46
首先,我嘗試了過去 stackoverflow 答案中的解決方案,這些答案的問題與我的問題相關,但沒有任何效果,這就是為什么我將其作為一個單獨的問題提出。我在 golang 中有兩個結構type otherPayments struct {    DebitTo     int    `json:"debit_To" binding:"required"`    CreditFrom  int    `json:"credit_from" binding:"required"`    OverallType string `json:"overall_type" binding:"required"`}type advanceAndRoomPayment struct {    PmID        int    `json:"pm_id" binding:"required"`        //Payment method id    PmName      string `json:"pm_name" binding:"required"`      //Payment method name    DebitTo     int    `json:"debit_To" binding:"required"`     //The ledger to debit from    CreditFrom  int    `json:"credit_from" binding:"required"`  //The ledger to credit from    OverallType string `json:"overall_type" binding:"required"` //Overall transaction type}我的postgresql 表中有5SQL 列booking_settingsinitial列,類型 = otherPayments,JSONBcancellation, 輸入 = otherPayments,JSONBupdation, 輸入 = otherPayments,JSONBadvance_payment輸入 = advanceAndRoomPayment,JSONB []room_payment, 輸入 = advanceAndRoomPayment,JSONB []查詢SELECT如下SELECT initial, cancellation, updation advance_payment, room_payment FROM booking_settings WHERE hotel_id = $1我使用的 sql 包是https://jmoiron.github.io/sqlx/我正在嘗試將上面的列掃描到它們適當的結構變量中,到目前為止我只能設法掃描initial, cancellation and updation而不是JSONB [] advance_payment and room_payment非常感謝任何幫助,謝謝
查看完整描述

1 回答

?
慕虎7371278

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}


查看完整回答
反對 回復 2023-02-06
  • 1 回答
  • 0 關注
  • 287 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號