JSON将数字视为base64 golang
试图将查询输出作为JSON发送到浏览器,但数字被视为Base64。整数输出正确JSON将数字视为base64 golang,json,go,Json,Go,试图将查询输出作为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);
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、数量数字/浮动):
{“ID”:1,“数量”:“OC4wMA==”}
{“ID”:2,“数量”:“OC4wMA==”}
如果没有JSON编码,数字列被视为正确的数字
编辑
@mkopriva希望这个答案有助于:
“如果您提供表定义以便我们可以看到列是如何定义的,那么查看SQL查询也会有所帮助,以便我们可以看到您是如何从数据库中提取列的”
如果您提供您提到的“将列正确视为数字”的代码及其输出,也会有所帮助。
给出以下结果:
地图[ID:1数量:9.75]
地图[ID:2数量:7.00]
“您能为我们执行fmt.Printf(“%T”,results[“QTY”])吗?如果“QTY”真的是int或float,json编码器会将其封送为base64字符串,这是非常值得怀疑的。
如果没有JSON,这将提供:
[]uint8
[]uint8
假设您使用的是
lib/pq
,quantity
值被转换成一个字节片,该字节片实际上是对应postgresnumeric
类型的正确类型。这是因为numeric
类型的值不能可靠地适合float64
而不降低精度,因此它会导致驱动程序选择将postgres数值
值转换为Go[]字节
值
请看这里:
但是,您可以通过将类型为*float64
的Go值传递给Scan
方法系列,明确地告诉驱动程序您需要一个float,并且驱动程序会将数值
转换为float64
,在这个过程中会丢失精度。但是如果传递接口{}
,驱动程序将做出最合适的选择,并将值转换为字节片
如果您不关心精度,但必须使用接口{}
作为扫描
的参数,则可以将表列的类型从数值
更改为浮点
,如果这样做,则驱动程序可以安全地选择将列转换为Go浮点64
如果您关心精度,但出于某种原因必须使用接口映射,则可以编写一个简单的函数,将映射中已知键的值从[]转换为字节
到字符串,之后,当您将更新后的映射传递给json编码器时,您将看到该键的值被编码为普通字符串,而不是base64
func bytesToString(k string, m map[string]interface{}) {
if b, ok := m[k].([]byte); ok {
m[k] = string(b)
}
}
假设您使用的是
lib/pq
,quaty
值被转换为字节片,该字节片实际上是对应postgresnumeric
类型的正确类型。这是因为numeric
类型的值不能可靠地适合float64
而不降低精度,因此驱动程序选择将postgres数值
值转换为Go[]字节
值是有意义的
请看这里:
但是,您可以通过将类型为*float64
的Go值传递给Scan
方法系列,明确地告诉驱动程序您需要一个float,并且驱动程序会将数值
转换为float64
,在这个过程中会丢失精度。但是如果传递接口{}
,驱动程序将做出最合适的选择,并将值转换为字节片
如果您不关心精度,但必须使用接口{}
作为扫描
的参数,则可以将表列的类型从数值
更改为浮点
,如果这样做,则驱动程序可以安全地选择将列转换为Go浮点64
如果您关心精度,但出于某种原因必须使用接口映射,则可以编写一个简单的函数,将映射中已知键的值从[]转换为字节
到字符串,之后,当您将更新后的映射传递给json编码器时,您将看到该键的值被编码为普通字符串,而不是base64
func bytesToString(k string, m map[string]interface{}) {
if b, ok := m[k].([]byte); ok {
m[k] = string(b)
}
}
经过无数次尝试,我找到了一个解决方案,通过将数字转换为字符串来解决问题。这并不理想,但相当简单
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)
}
请随意投反对票,但请允许我解释原因。经过无数次尝试,我找到了一个解决方案,通过将数字转换为字符串来解决问题。这并不理想,但相当简单
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)
}
请随意向下投票,但请允许我解释原因。如果您已经知道返回结果的结构,那么为什么不使用struct,然后将其发送给browserI?我不知道该结构。从表中选择*。这意味着您的DB驱动程序返回的不是数字,而是字节片,
[]字节
,这就是它们被封送为JSON base64编码的原因。您必须找出这些列的实际DB数据类型,这些列包含您认为是数字的内容,然后问一个更全面的问题,以便我们能够有根据地猜测数据库类型与Go类型之间的不匹配情况。@kostix It在Postgresql中存储为数字,在不使用JSON时显示为数字。因此,它可能是Postgresql驱动程序?告诉您哪些类型被视为[]字节
。如果您已经知道返回结果的结构,那么为什么不使用struct,然后将其发送到browserI?我不知道该结构。请从表中选择*。这意味着您的DB驱动程序返回的不是数字,而是字节片,[]字节
,这就是它们被封送为JSON base64编码的原因。您必须找出这些列的实际DB数据类型,这些列包含您认为是数字的内容,然后问一个更全面的问题,以便我们能够