Scan into struct
- 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
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