Golang Gin REST API POST正常但GET查询数据报错问题排查
问题排查与解决
1. 字段顺序不匹配
你用SELECT * FROM table查询时,返回的字段顺序必须和rows.Scan的参数顺序完全一致。从你的INSERT语句看,表字段顺序大概率是id, title, body, titles, contents, date,但你当前Scan的顺序把Date放在了数组字段前面,这会导致类型匹配错误。
解决:要么明确指定SELECT的字段顺序(推荐,避免表结构变更出问题),要么调整Scan参数顺序:
// 明确指定字段,和结构体字段对应 rows, err := db.Query("SELECT id, title, body, titles, contents, date FROM table") // Scan顺序严格对应查询字段 err := rows.Scan(&job.ID, &job.Title, &job.Body, pq.Array(&job.Titles), pq.Array(&job.Contents), &job.Date)
2. 数组类型扫描错误
PostgreSQL的数组类型不能直接扫描到Go的固定长度数组[4]string里,必须像插入时那样用pq.Array()包裹指针,否则会触发类型不匹配错误,这是GET接口失败的核心原因。
解决:扫描数组字段时用pq.Array()包裹:
err := rows.Scan( &job.ID, &job.Title, &job.Body, pq.Array(&job.Titles), pq.Array(&job.Contents), &job.Date, )
3. 错误信息太笼统
你当前的错误提示都是“failed to retrieve jobs”,根本没法定位具体问题。应该把原始错误信息返回,方便排查:
if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to scan job: %v", err)}) return }
4. 遗漏遍历后的错误检查
rows.Next()返回false不一定是遍历结束,也可能是出错了,必须在循环结束后检查rows.Err():
for rows.Next() { // 现有遍历代码 } // 检查遍历过程中是否出现错误 if err := rows.Err(); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("rows iteration error: %v", err)}) return }
修正后的GET接口完整代码
r.GET("/jobs", func(c *gin.Context) { rows, err := db.Query("SELECT id, title, body, titles, contents, date FROM table") if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to query jobs: %v", err)}) return } defer rows.Close() jobs := []Job{} for rows.Next() { var job Job err := rows.Scan( &job.ID, &job.Title, &job.Body, pq.Array(&job.Titles), pq.Array(&job.Contents), &job.Date, ) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to scan job: %v", err)}) return } jobs = append(jobs, job) } if err := rows.Err(); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("rows iteration error: %v", err)}) return } c.JSON(http.StatusOK, jobs) })
内容的提问来源于stack exchange,提问作者Coding write
相关产品推荐
相关产品推荐

