【问题标题】:Using jsonb_agg/jsonb_build_object to parse to inner structs使用 jsonb_agg/jsonb_build_object 解析到内部结构
【发布时间】:2021-01-15 13:05:43
【问题描述】:

每当我尝试获取(选择/扫描)组(外部结构)及其协作者(内部结构)时,我都会收到以下错误: // sql: Scan error on column index ..., name "collaborators": unsupported Scan, storing driver.Value type []uint8 into type *[]User

我正在使用 sqlx(带有 pgx 驱动程序)。

从 db 获取的代码是:

func (psql *Postgres) GetGroups(someParam string) ([]Group, error) {
   groups := []Group{}
   err := psql.db.Unsafe().Select(&groups, <the query ...>, someParam)
   ....
}

type Postgres struct {
    db      *sqlx.DB
    config  *config.PostgresDB
    timeout time.Duration
}

这是 SQL 查询:

SELECT groups.id, 
       groups.title,
       JSONB_AGG(JSONB_BUILD_OBJECT(
        'id', u.id,
        'first_name', u.first_name, 
        'last_name', u.last_name,
        'user_pic_url', u.user_pic_url)) as collaborators
FROM groups
JOIN user_group_permissions p
ON   p.group_id = groups.id
JOIN users u
ON   u.id = p.user_id

这些是结构:

type Group struct {
    Id             string  `json:"id" db:"id"`
    Title          string  `json:"title"   db:"title"`
    Collaborators  []User  `json:"collaborators" db:"collaborators"`
}

type User struct {
    Id            string  `json:"id" db:"id"`
    FirstName     string  `json:"first_name" db:"first_name"`
    LastName      string  `json:"last_name" db:"last_name"`
    ProfilePhoto  *string `json:"profile_photo" db:"user_pic_url"`
}

我有一个简单的 Group 表、一个 User 表和一个代表所有具有该组权限的用户的表:

CREATE TABLE groups (
   id    int UNIQUE NOT NULL generated always as identity,
   title text
)

CREATE TABLE users (
    id       bigint UNIQUE NOT NULL generated always as identity,
    first_name   text NOT NULL,
    last_name    text NOT NULL,
    user_pic_url text
)
CREATE TABLE user_group_permissions (
   group_id   unsigned_int,
   user_id    unsigned_bigint,
   permission unsigned_smallint,
)


CREATE DOMAIN unsigned_smallint AS smallint
   CHECK(VALUE >= 0 AND VALUE < 32767);

CREATE DOMAIN unsigned_int AS int
   CHECK(VALUE >= 0 AND VALUE < 2147483647);

CREATE DOMAIN unsigned_bigint AS bigint
   CHECK(VALUE >= 0 AND VALUE < 9223372036854775807);

【问题讨论】:

    标签: sql postgresql go sqlx pgx


    【解决方案1】:
    import "encoding/json"
    
    type Group struct {
        Id             string   `json:"id" db:"id"`
        Title          string   `json:"title"   db:"title"`
        Collaborators  UserList `json:"collaborators" db:"collaborators"`
    }
    
    type User struct {
        Id            string  `json:"id" db:"id"`
        FirstName     string  `json:"first_name" db:"first_name"`
        LastName      string  `json:"last_name" db:"last_name"`
        ProfilePhoto  *string `json:"profile_photo" db:"user_pic_url"`
    }
    
    type UserList []User
    
    func (list *UserList) Scan(src interface{}) error {
        var data []byte
        switch v := src.(type) {
        case []byte:
            data = v
        case string:
            data = []byte(v)
        default:
            return nil // or return some error
        }
        return json.Unmarshal(data, list)
    }
    

    【讨论】:

      猜你喜欢
      • 2017-09-16
      • 1970-01-01
      • 2019-11-23
      • 2019-01-08
      • 1970-01-01
      • 2020-04-03
      • 2019-01-17
      • 2010-09-21
      • 2019-10-15
      相关资源
      最近更新 更多