JSON将数字视为base64 golang

时间:2018-04-06 08:47:45

标签: 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); 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

2 个答案:

答案 0 :(得分:3)

假设您正在使用lib/pqQTY值正在转换为字节切片,实际上是相应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

https://play.golang.org/p/Ekih0oLd4-L

答案 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)
}

请随意投票,但请我帮助解释原因。