【问题标题】:Timestamp columns missing with postgrespostgres 缺少时间戳列
【发布时间】:2019-04-29 00:30:12
【问题描述】:

我有一个名为 certs 的 Postgres 表,有 4 列。

enter code here
\d certs
                        Table "public.certs"
Column       |            Type             | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+---------
uuid         | character varying(255)      |           | not null |
serialnumber | bigint                      |           |          |
validtill    | timestamp without time zone |           |          |
validfrom    | timestamp without time zone |           |          |
Indexes:
"certs_pkey" PRIMARY KEY, btree (uuid)

如您所见,最后两列的类型为timestamp。现在我尝试通过以下方式读取列中的所有行

res, err := sql.DB.Query("SELECT * from certs;")
if err == nil{
    log.Fatal(err)
}
fmt.Println(res.Columns())
defer res.Close()
var id string
var serialNumber int64
var validFrom time.Time
var validTill time.Time
fmt.Println(res.ColumnTypes())
for res.Next() {
    err := res.Scan(&id, &serialNumber, &validFrom, &validTill)
    fmt.Println(res.Columns())
    if err != nil {
        log.Errorf("error %v", err)
    } else {
        cs.Certs[id] = serialNumber
    }

基本上我正在尝试解码检索到的值。

我收到以下错误

 error sql: expected 2 destination arguments in Scan, not 4

还有 print res.columns() 打印这个

[uuid serialnumber] <nil>

如您所见,存在错误,并且打印的 columns 未显示 validtillvalidfrom。使用psql 独立检查数据库确实可以验证validtillvalidfrom 列中是否包含数据。

我在这里缺少什么?为什么会出错?

【问题讨论】:

  • 你确定你的 Go 程序和 psql 都连接到同一个数据库吗?您是否更改了 Go 程序中的 search_path 以便它以不同的模式查询 certs 表?你有权限阅读这些专栏吗?如果您明确提及它们(SELECT uuid, ... 而不是 SELECT *)会发生什么?
  • 看起来您的表格确实缺少这些列。我同意彼得的观点:确保您要连接的数据库实际上在该表上有这些列。
  • @Peter,不可能。我验证了它们。我在同一个代码库中做了一个小改动来删除表,当通过 psql 检查时,表被删除了。如果 go 应用连接到其他数据库,然后连接到 psql,则不会删除证书表。
  • 你能通过普通的sql查询得到你想要的吗?可以将 Select Stirng from * 更改为 uuid、serialnumber、validtill、validfrom 吗?

标签: postgresql go timestamp


【解决方案1】:

在 Go 中有一种处理可空字段的特定方法。您应该使用可空类型,如sql.NullStringsql.NullInt64 等。否则会出现扫描错误。

您还应该在 res.Next 块内为 Scan 定义变量。

本文详细解释了如何使用它-https://pliutau.com/working-with-db-nulls/

【讨论】:

  • 这与问题无关。空字段仍将显示在结果中——如 nil
  • 也许可以,但这并不能成为问题的答案。
  • @AlexPliutau,我将架构更改为使列不再可以为空,但问题仍然存在。
  • @amrx:需要明确的是,没有理由将架构更改为不可为空。这与您的情况完全无关。
  • @amrx 您还应该在 res.Next 块内定义用于扫描 (var ...) 的局部变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 2013-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多