将BigQuery的具有null的行映射到struct后发生异常

时间:2018-06-26 10:20:06

标签: go google-bigquery gcloud

我有一个具有以下架构的BigQuery表:

name    STRING  NULLABLE     
age     INTEGER NULLABLE  
amount  INTEGER NULLABLE

和这两行:

1   Batgirl 23  123  
2   Batman  22  null     

我想做的是从这张桌子上的“转到”中选择一个,这确实很好:

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

上面的代码就像一个超级按钮一样工作,它获得选择并打印出两行,如下所示:

[Batman 22 <nil>]
[Batgirl 23 123]

蝙蝠侠显示为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)
}

以上代码对结果查询进行了迭代,并将两个值都存储在我稍后可以操作的结构中。当没有空列时,它可以正常工作(由于我在Batman上的数量为空,所以现在不属于我的情况),所以我遇到下一个错误:

bigquery: NULL values cannot be read into structs

我试图解决的问题是使struct字段可以为空:

type test struct {
    Name   string
    Age    int
    Amount int `bigquery:",nullable"`
}

但这基本上什么都不做。我开始学习Go,但我并不真正理解为什么我不能在结构中使用nil值或如何解决此问题,所以这是我的两个问题:

  1. 如何存储具有空值的行结果?

  2. 为什么Google决定不能在结构字段上设置nil值?

1 个答案:

答案 0 :(得分:4)

您可以使用任何bigquery。可以看到in this link的null类型:

STRING      NullString
BOOL        NullBool
INTEGER     NullInt64
FLOAT       NullFloat64
TIMESTAMP   NullTimestamp
DATE        NullDate
TIME        NullTime
DATETIME    NullDateTime

在您的情况下,您必须更改行

Amount int `nullable`

收件人:

Amount bigquery.NullInt64

same link中指出:

  

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