尝试将查询输出作为JSON发送到浏览器,但数字被视为Base64。整数打印出来是正确的。
var rows *sqlx.Rows
enc := json.NewEncoder(w)
rows, err = db.Queryx(query)
for rows.Next() {
results := make(map[string]interface{})
err = rows.MapScan(results)
if err := enc.Encode(results); err != nil{
fmt.Fprintf(w,"%s\n", results)
}
}
JSON的结果是(id integer,qty numeric / float):
{“ID”:1,“QTY”:“OC4wMA ==”}
{ “ID”:2 “QTY”: “OC4wMA ==”}
如果没有JSON编码,数字列将被视为数字。
修改
@mkopriva希望这个答案有所帮助:
“如果您提供表定义,以便我们可以看到列的定义方式,它也有助于查看SQL查询,以便我们可以看到您如何从数据库中提取列”
"ID" int4
"QTY" numeric
SELECT * FROM table
如果你提供的代码及其输出你将“正确地将列视为数字”
,它也会有所帮助var rows *sqlx.Rows
rows, err = db.Queryx(query)
for rows.Next() {
results := make(map[string]interface{})
err = rows.MapScan(results)
fmt.Fprintf(w,"%s\n", results)
}
给出了这个结果:
地图[ID:1 QTY:9.75]
地图[ID:2数量:7.00]
“你能为我们做fmt.Printf(”%T“,结果[”QTY“])吗?如果”QTY“真的是一个整数编码器会编组的int或float,这是非常值得怀疑的它作为base64字符串。
没有JSON,这给出了:
[] UINT8 [] UINT8
答案 0 :(得分:3)
假设您正在使用lib/pq
,QTY
值正在转换为字节切片,实际上是相应postgres的{em>正确类型{{1 }类型。这是因为类型numeric
的值无法在不失去精度的情况下可靠地放入numeric
,因此驱动程序选择将postgres float64
值转换为Go { {1}}值。
见这里:https://github.com/lib/pq/issues/648#issuecomment-322674708
但是,您可以通过将numeric
类型的Go值传递给[]byte
方法系列,明确告诉驱动程序您需要浮点数,驱动程序将转换*float64
进入Scan
,在此过程中失去了精确性。但是如果你传递numeric
,驱动程序将做出最合适的选择并将值转换为字节切片。
如果您不关心精确度,但必须使用float64
作为interface{}
的争论,则可以从interface{}
更改表格列的类型到Scan
,如果您这样做,那么驱动程序可以安全地选择将您的列转换为Go numeric
。
如果您关心精度,但由于某种原因您必须使用接口地图,您可以编写一个简单的函数,将地图中已知的键值从float
转换为float64
之后,当您将更新的地图传递给json编码器时,您会看到该键的值被编码为普通字符串而不是base64。
[]byte
答案 1 :(得分:0)
经过无数次尝试,我找到了一种解决方案,通过将数字转换为字符串来解决问题。不理想,但相当简单。
var rows *sql.Rows
rows, err = db.Query(query)
cols, _ := rows.Columns()
colnames, _ := rows.Columns()
vals := make([]interface{}, len(cols))
for i, _ := range cols { //bytes to string
vals[i] = &cols[i]
}
mymap := make(map[string]interface{})
for i, v := range vals { //adding column names
mymap[colnames[i]] = v
}
for rows.Next() {
err = rows.Scan(vals...)
json, _ := json.Marshal(mymap)
fmt.Fprintf(w,"%s\n",json)
}
请随意投票,但请我帮助解释原因。