georgysavva / scany

Library for scanning data from a database into Go structs and more
MIT License
1.29k stars 68 forks source link

Scanning postgres array columns into map[string]interface{} #64

Closed andersarpi closed 2 years ago

andersarpi commented 3 years ago

Thanks a lot for this great library!

I try to scan a query where some of the columns are arrays, with the destination being a map[string]interface{}. This works fine for all columns, but the array columns don't turn into slices, but instead an object with a structure like this:

"myArray": {
    "Elements": ["my first value"],
    "Dimensions": [
      {
        "Length": 1,
        "LowerBound": 1
      }
    ],
    "Status": 2
  }

What I actually expected is:

"myArray": ["my first value"]

Is this intentional? Is there some way to get around this? If I scan into a struct with slice fields, it works fine. But for my use case, a map is needed.

georgysavva commented 3 years ago

Hello and thank you for opening the issue. Could you please provide the SQL query and the Go code on how you call scany library.

lamualfa commented 2 years ago

@georgysavva sorry, just want to ask, is scany support scanning into map[string]interface (single data, no rows)? what the data type will be use by default? uint8 which is user need to parse the data type manually? or scany will automatically convert the data into the original type that defined in database?

georgysavva commented 2 years ago

@lamualfa Hello. Could you also provide an example of your SQL query and how would you call scany library. So I could better understand your case please.

lamualfa commented 2 years ago

@georgysavva

var session map[string]interface{}

// select only 1 data.
rows, err := db.Query(context.Background(), `select * from sessions where id=$1 limit 1;`, sessionId)
if err != nil {
    return errors.WithStack(err)
}

// i don't know eaxctly how to use ScanOne. but for sure i want scany to scan into a map, not an array.
pgxscan.ScanOne(&session, rows)

fmt.Printf("session id is %s.", session["id"].(string))

i use pgx.

georgysavva commented 2 years ago

@lamualfa Hey. You are using ScanOne() correctly and scany should fill the session map variable with data from your single row. Regarding the data types inside the map: scany doesn't do anything to affect them. The database library (pgx) parses the database column type and assigns the corresponding Go type. After that, you need to type assign them as you've shown session["id"].(string) and convert if needed.