You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go与PostgreSQL单元测试插入整数时出现nil转int64扫描错误

解决Go单元测试中sql: Scan error on column index 0的问题

看起来你遇到的问题有点反直觉——明明给testDevice的ID设成了整数1,插入后却触发了nil转int64的Scan错误。我来帮你拆解下可能的原因和解决办法:

核心问题分析

这个错误本质是:数据库返回的第一条列(也就是你的ID列)值为nil,但你的结构体ID字段是int64类型,无法接收nil值。哪怕你手动设置了ID=1,也可能被数据库的规则覆盖,导致返回值异常。

排查&解决步骤

1. 先检查Device结构体的DB标签配置

大概率是结构体的字段映射出了问题,尤其是ID字段的标签。假设你用的是sqlx的Dbmap,正确的结构体定义应该类似这样:

type Device struct {
    ID   int64  `db:"id,primarykey,autoincr"` // 重点:标签要匹配表字段,自增主键需加autoincr
    Guid string `db:"guid"`
    Name string `db:"name"`
}
  • 如果你的ID字段没有加db标签,或者标签名和数据库表字段不匹配,Dbmap无法正确映射数据库返回的ID值;
  • 如果ID是自增主键,必须加上autoincr标签,这样Dbmap才会自动把数据库生成的ID填充回结构体。

2. 确认数据库表结构是否合理

检查你的devices表(假设表名是这个)的id字段配置:

  • 如果是自增主键,必须设置为AUTO_INCREMENT(MySQL)或SERIAL(PostgreSQL),且不能允许NULL;
  • 如果不是自增主键,要确保字段不允许NULL,且插入时手动设置的ID=1能被数据库正常接收(比如没有主键冲突、触发器修改ID等情况)。

举个MySQL的正确表结构示例:

CREATE TABLE devices (
    id INT AUTO_INCREMENT PRIMARY KEY,
    guid VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL
);

3. 调整插入逻辑,匹配自增规则

如果ID是自增主键,不要手动设置ID值——数据库会自动生成,Dbmap会把生成的ID填充回你的结构体:

func Test1(t *testing.T){
    //Code
    testDevice := Device{ Guid: "C6", Name: "test device", } // 去掉手动设置的ID
    err := Dbmap.Insert(&testDevice)
    So(err, ShouldBeNil)
    // 此时testDevice.ID已经被填充为数据库生成的自增ID
    //More code
}

如果你强行手动设置自增ID,部分数据库会忽略你的值,返回自己生成的ID;如果结构体标签没配置好,就会出现nil转int64的错误。

4. 开启SQL日志定位细节

如果以上步骤都没解决问题,建议开启Dbmap的SQL日志,查看实际执行的SQL和返回结果:

import "log"
import "os"

func init() {
    // 在测试初始化时开启SQL追踪
    Dbmap.TraceOn("", log.New(os.Stdout, "SQL: ", log.Lmicroseconds))
}

这样你能清楚看到插入语句的实际执行情况,以及数据库返回的字段值,更容易定位到底是哪一步出了问题。

内容的提问来源于stack exchange,提问作者Errorum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:59:47