从 BigQuery 检索多行的通用 Go 代码

问题描述 投票:0回答:1

我正在编写一些实用程序,以使用 Go 以通用方式从 BigQuery 检索多行。 例如

type User struct {name string, surname string}
type Car struct {model string, platenumber string}

query1:="SELECT name, surname FROM UserTable"
query2:="SELECT model, platenumber FROM CarTable"

cars, _ := query2.GetResults()
users, _ := query1.GetResults()
OR
cars := []Car{}
query2.GetResults(cars) // and it would append to the slice

我不确定

GetResults
的签名。我需要以某种方式将类型传递给 BigQuery 库,以便它可以检索数据并将其正确映射到结构。但同时我需要使其通用,以便它可以用于不同类型。

目前我的

GetResults
看起来像这样:它不起作用,错误是:

bigquery:无法将 *interface {} 转换为 ValueLoader(需要指向 []Value、map[string]Value 或 struct 的指针)[]

但是我不能直接传递该结构,因为我想使其通用。

func (s *Query) GetResults() ([]interface{}, error) {
    var result []interface{}

    job, err := s.Run()
    if err != nil {
        s.log.Error(err, "error in running the query")
        return nil, err
    }

    it, err := job.ReadData()
    if err != nil {
        s.log.Error(err, "error in reading the data")
        return nil, err
    }
    var row interface{}
    for {
        err := it.Next(&row)
        if err != nil {
            fmt.Print(err)
            break
        }
        result = append(result, row)
    }
    return result, nil
}

还有其他方法可以实现这一目标吗?或者不创建这样的方法是好方法吗?

我已经尝试了很多不同的事情,有或没有指针,有或没有数组,通过修改参数,或返回一个新列表,似乎没有任何效果,并且就性质而言,做所有这些感觉有点错误我想要实现的目标“简单”。

我还考虑过执行以下操作

GetResults[T any]() ([]T, error)

但它被“排除”,因为

GetResults
是接口的一部分(并且我们不能为接口的方法定义泛型)。我不能/不想为所有接口定义类型,因为它会影响其他接口。

go generics google-bigquery interface
1个回答
0
投票

基本上

bigquery.Value
interface{}
的基础,因此您可以使用它,在代码中将
interface{}
替换为
bigquery.Value
。 这是我的代码的示例:

func (srv *SBigQuery) GBQReadQueryToStruct(ctx context.Context, query string) ([]map[string]bigquery.Value, error) {
var results []map[string]bigquery.Value
// Construct a query.
q := srv.Query(query)

// Execute the query.
it, err := q.Read(ctx)
if err != nil {
    return nil, fmt.Errorf("unable to read query: %v", err)
}

// Iterate through the results.
var row map[string]bigquery.Value
for {
    err := it.Next(&row)
    if err == iterator.Done {
        break
    }
    if err != nil {
        return nil, fmt.Errorf("unable to iterate through query results: %v", err)
    }
    results = append(results, row)
}

return results, nil

}

参考:

  1. https://cloud.google.com/go/docs/reference/cloud.google.com/go/bigquery/1.16.0#cloud_google_com_go_bigquery_Value
© www.soinside.com 2019 - 2024. All rights reserved.