如何将jsonb对象从Postgresql扫描到golang结构



首先,我尝试了过去stackoverflow答案的解决方案,这些答案的问题与我的问题有关,但没有任何效果,这就是为什么我将其作为一个单独的问题来问。

我在戈兰中有两个结构

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
}

在我的booking_settingspostgresql表中有5SQL列

  • initial列,类型=otherPaymentsJSONB
  • cancellation,类型=otherPaymentsJSONB
  • updation,类型=otherPaymentsJSONB
  • advance_payment类型=advanceAndRoomPaymentJSONB []
  • room_payment,类型=advanceAndRoomPaymentJSONB []

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

非常感谢任何帮助,谢谢

以防万一,jsonb[]是一个PostgreSQL数组类型,其元素类型为jsonb。它不是一个";json数组";类型

如果要将JSON数据存储在列中,则应使用json/jsonb类型,无论您希望数据包含标量、对象还是数组JSON值。

因此,除非您在选择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阵列,然后对单个元素进行解组,也可以将这项工作委托给一些第三方实现。

以下是使用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数组,那么您需要了解用于表示此类数组的语法。您可以在此处找到相关文档:

数组值的外部文本表示由项组成根据数组的元素类型,加上指示数组的装饰结构装饰由周围的花括号({和}(组成数组值加上相邻项之间的分隔符。这个分隔符通常是逗号(,(,但也可以是其他字符:它由数组元素类型的typdelim设置决定。在PostgreSQL发行版中提供的标准数据类型中,除了使用分号(;(的类型框外,所有类型框都使用逗号。

例如,如果您有一个包含json对象、json数组、json字符串和json布尔的pg数组,并且您选择了它,那么将传递给sql.Scanner实现的数组表示将类似于:

{"{"foo": "bar"}","["foo", "bar"]",""foo bar"",true}

相关内容

  • 没有找到相关文章