简体   繁体   中英

How to properly scan the results of the array_agg function in Golang?

In my Golang (1.15) application I use sqlx package to work with the PostgreSQL database (PostgreSQL 12.5).

My SQL request has an array_agg function that returns the array of strings or null if it's empty.

I am trying to Scan the results of this SQL request but it raises the next error in my program:

sql: Scan error on column index 3, name "organization_ids": unsupported Scan, storing driver.Value type string into type *[]string

Code snippet :

type Channel struct {
    ChannelId           *string   `db:"channel_id" json:"channelId"`
    ChannelName         *string   `db:"channel_name" json:"channelName"`
    OrganizationsIds    *[]string `db:"organizations_ids" json:"organizationsIds"`
}

var channel Channel

row := db.QueryRow(`
    select
        channels.channel_id::text,
        channels.channel_name::text,
        array_agg(distinct channels_organizations_relationship.organization_id)::text[] organizations_ids
    from
        channels
    left join channels_organizations_relationship on
        channels.channel_id = channels_organizations_relationship.channel_id
    where
        channels.channel_id = $1
    group by
        channels.channel_id
    limit 1;`, *channelId)

if err := row.Scan(&channel.ChannelId, &channel.ChannelName, &channel.OrganizationsIds); err != nil {
    fmt.Println(err)
}

return &channel

I also tried to change the data type of the OrganizationsIds field in the Channel struct to *pg.StringArray from the github.com/lib/pq package. In this case, when I Scan , I get the following error in my program:

sql: Scan error on column index 3, name "organizations_ids": unsupported Scan, storing driver.Value type string into type *[]pq.StringArray

My task is to return a list of strings or null/nil to the client for this column.

Can someone explain how to fix this strange behavior?

Well, finally I found the solution of my problem.

I noticed that the array_agg function returns the [null] . I changed the SQL request a little bit to return the null instead of [null] . I make it with this changes:

array_agg(distinct channels_organizations_relationship.organization_id) filter (where channels_organizations_relationship.organization_id is not null)

In this article ( Postgres returns [null] instead of [] for array_agg of join table ), you can find many different solutions to this problem.

Then you can use one of this solutions:

The 1 option

We can use OrganizationsIds pq.StringArray in the struct, and then when scanning do this row.Scan(..., &channel.OrganizationIds .

The 2 option

We can use OrganizationsIds []string in the struct, and then when scanning do this row.Scan(..., (*pq.StringArray)(&channel.OrganizationIds)) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM