将 bigquery 的行与 null 映射到结构后出现异常

Bla*_*erg 3 go google-bigquery gcloud

我有一个带有此架构的 BigQuery 表:

name    STRING  NULLABLE     
age     INTEGER NULLABLE  
amount  INTEGER NULLABLE
Run Code Online (Sandbox Code Playgroud)

和这两行:

1   Batgirl 23  123  
2   Batman  22  null     
Run Code Online (Sandbox Code Playgroud)

我想要做的是从这张桌子上的 Go 中选择一个,它工作得很好:

ctx := context.Background()
client, err := bigquery.NewClient(ctx, projectID)

q := client.Query("SELECT * FROM test.user_test LIMIT 1000")

it, err := q.Read(ctx)
if err != nil {
    log.Fatal(err)
}
for {
    var values []bigquery.Value
    err := it.Next(&values)
    if err == iterator.Done {
        break
    }
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(values)
}
Run Code Online (Sandbox Code Playgroud)

上面的代码就像一个魅力一样工作,它获取选择并像这样打印两行:

[Batman 22 <nil>]
[Batgirl 23 123]
Run Code Online (Sandbox Code Playgroud)

蝙蝠侠显示为 nil 值。当我尝试使用以下代码将此行存储在结构中时,问题就出现了:

type test struct {
    Name   string
    Age    int
    Amount int `nullable`
}

q := client.Query("SELECT * FROM test.test_user LIMIT 1000")

if err != nil {
    log.Fatal(err)
}

it, err := q.Read(ctx)
if err != nil {
    log.Fatal(err)
}
for {
    var c test
    err := it.Next(&c)
    if err == iterator.Done {
        break
    }
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(c)
}
Run Code Online (Sandbox Code Playgroud)

上面的代码迭代结果查询,并将两个值存储在一个结构中,我可以稍后操作。当没有任何空列时它工作正常(这不是我现在的情况,因为我在 Batman 上有一个空值),所以我收到下一个错误:

bigquery: NULL values cannot be read into structs
Run Code Online (Sandbox Code Playgroud)

我试图解决这个问题是使结构字段可以为空,如下所示:

type test struct {
    Name   string
    Age    int
    Amount int `bigquery:",nullable"`
}
Run Code Online (Sandbox Code Playgroud)

但这基本上没有任何作用。我开始学习 Go 并且我真的不明白为什么我不能在结构中使用 nil 值或者我如何解决这个问题,所以这是我的两个问题:

  1. 如何使用空值存储我的行结果?

  2. 为什么 google 决定不能在 struct 字段上设置 nil 值?

Vic*_*GGl 7

您可以使用在此链接中可以看到的任何 bigquery.Null 类型:

STRING      NullString
BOOL        NullBool
INTEGER     NullInt64
FLOAT       NullFloat64
TIMESTAMP   NullTimestamp
DATE        NullDate
TIME        NullTime
DATETIME    NullDateTime
Run Code Online (Sandbox Code Playgroud)

在你的情况下,你将不得不改变你的线路

Amount int `nullable`
Run Code Online (Sandbox Code Playgroud)

到:

Amount bigquery.NullInt64
Run Code Online (Sandbox Code Playgroud)

同一个链接中,它指出:

尝试将 BigQuery NULL 值读入结构字段是错误的,除非该字段的类型为 []byte 或特殊的 Null 类型之一:NullInt64、NullFloat64、NullBool、NullString、NullTimestamp、NullDate、NullTime 或 NullDateTime .