首先,我尝试了过去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_settings
postgresql表中有5
SQL列
initial
列,类型=otherPayments
,JSONB
cancellation
,类型=otherPayments
,JSONB
updation
,类型=otherPayments
,JSONB
advance_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
非常感谢任何帮助,谢谢
以防万一,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}