jackc / jackc/pgx

Scan into struct

Open
#627 9 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
14.3k
Forks
1.1k
Avg merge
6d 9h
Merged PRs (30d)
11

Description

Requesting guidance or feature request on scanning rows into a struct.

I know you can query/select data and then unmarshal using the `row_to_json` func as described in [issue 180](https://github.com/jackc/pgx/issues/180#issuecomment-247763399). But this is limited to only selecting (from what I've experienced).

It would be handy to be able to scan into a struct when `to_json` isn't available as a function. or the overhead is too much.

Here is a basic scan helper that I've implemented. It's super limited atm, but it does allow for things like `[]inteface{&User.ID, &User.Name, &User.Foo}` and scan a returned jsonb object into an initialized struct or struct slice `[]User`.
```go
// returned jsonb object of two rows
uu := make(User, 0)
for rows.Next() {
if err := scan(&uu, rows); err != nil {
fmt.Println(err.Error())
return
}
}

func scan(i interface{}, rows pgx.Rows) error {
v := reflect.ValueOf(i)
if v.Kind() == reflect.Interface {
v = v.Elem()
}
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
switch v.Kind() {
case reflect.Struct: // only works if scanning from a json object
if err := rows.Scan(i); err != nil {
return err
}
case reflect.Slice:
if ii, ok := v.Interface().([]interface{}); ok {
if err := rows.Scan(ii...); err != nil {
return err
}
return nil
} else {
mock := reflect.MakeSlice(v.Type(), 1, 1)

ty := reflect.New(mock.Index(0).Type())
vv := ty.Interface()
if err := scan(vv, rows); err != nil {
return err
}
v.Set(reflect.Append(v, reflect.ValueOf(vv).Elem()))
}
}
return nil
}
```

The above code is still super limited and doesn't work for most use cases, however, with some feedback / guidance or maybe if you see value in this functionality this can be done without crossing too much into the ORM world.

Contributor guide

Open the contributing guide

Research direction

Start with the issue's scan helper and the pgx.Rows.Scan entry point described in the report. Review the stated struct, struct-slice, and non-JSON scanning examples before defining the supported behavior. Done would require an agreed scope and guidance or an API design, but the issue does not name files or tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, postgresql
Domain
backend, databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.