Show keys in result of sqlx.StructScan in Go templates

If I use this less idiomatic way, the values shows up in a Go template.

var list []map[string]interface{}
	rows, err := db.Queryx("SELECT hr_id, hr_sign, hr_code, hr_sum FROM hr")

	if err != nil {
		log("get error" + err.Error())
	}

	defer rows.Close()

	for rows.Next() {
		row := make(map[string]interface{})
		err = rows.MapScan(row)
		if err != nil {
			log("next " + err.Error())
		}
		list = append(list, row)
	}

The result will be both key AND value:

[map[hr_code:PM hr_date:2020-08-26 00:00:00 +0000 +0000 hr_id:135 hr_job:20-0002 hr_ppu:[49 48 48 48 46 48 48] hr_qty:[48 46 50 53] hr_sign:JD hr_subject:test hr_sum:[50 53 48 46 48 48]] map[hr_code:PM hr_date:2020-08-26 00:00:00 +0000 +0000 hr_id:138 hr_job:20-0002 hr_ppu:[49 48 48 48 46 48 48] hr_qty:[49 46 48 48] hr_sign:JD hr_subject:test hr_sum:[49 48 48 48 46 48 48]]]

Trying a more idiomatic way using Structs:

type Hr struct {
	Hr_id   int     `db:"hr_id"`
	Hr_sign string  `db:"hr_sign"`
	Hr_code string  `db:"hr_code"`
	Hr_sum  float64 `db:"hr_sum"`
}

rows, err := db.Queryx("SELECT hr_id, hr_sign, hr_code, hr_sum FROM hr")
defer rows.Close()
result := []Hr{}
for rows.Next() {
	row := Hr{}
	err := rows.StructScan(&row)
	if err != nil {
		log("getsql error" + err.Error())
	}
	result = append(result, row)
}

fmt.Println(result)

Only the values appear. No keys. And the Go template shows nothing.

[{135 JD PM 250} {138 JD PM 1000} {139 JD PM 1250} {140 JD PM 250} {141 JD PM 250} {142 JD PM 1250} {143 JD PM 1250} {144 JD PM 1250} {145 JD PM 1250} {146 JD PM 1250} {147 JD PM 1250} {148 JD PM 250} {149 JD PM 250} {150 JD PM 250} {151 JD PM 250} {152 JD PM 250} {153 JD PM 250} {154 JD PM 500} {155 JD PM 500} {156 JD PM 500} {157 JD PM 750} {158 JD PM 750} {159 JD PM 750} {160 JD PM 750} {161 JD PM 750}]

What am I doing wrong?

Mak Hr implement the Stringer interface:

type Stringer interface {
    String() string
}

Like this:

package main

import (
	"fmt"
)

type Hr struct {
	Hr_id   int     `db:"hr_id"`
	Hr_sign string  `db:"hr_sign"`
	Hr_code string  `db:"hr_code"`
	Hr_sum  float64 `db:"hr_sum"`
}

func (hr Hr) String() string {
	return fmt.Sprintf("ID=%d, Sign=%s, Code=%s, Sum=%f", hr.Hr_id, hr.Hr_sign, hr.Hr_code, hr.Hr_sum)
}

func main() {
	hr := Hr{Hr_id: 123, Hr_sign: "The Sign", Hr_code: "The Code", Hr_sum: 1.234}
	fmt.Println(hr)
}

Output:

ID=123, Sign=The Sign, Code=The Code, Sum=1.234000

See https://play.golang.org/p/4dVU4wcHYSh

I suggest to rename the properties of Hr:

type Hr struct {
	Id   int     `db:"hr_id"`
	Sign string  `db:"hr_sign"`
    Code string  `db:"hr_code"`
	Sum  float64 `db:"hr_sum"`
}

This will make your code much easier to read.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.