我正在嘗試運行以下流程:
- 從某處獲取資料
- 創建新的本地 CSV 檔案,將資料寫入該檔案
- 將 CSV 上傳到 Bigquery
- 洗掉本地檔案
但它似乎加載了空資料。這是代碼:
func (c *Client) Do(ctx context.Context) error {
bqClient, err := bigquerypkg.NewBigQueryUtil(ctx, "projectID", "datasetID")
if err != nil {
return err
}
data, err := c.GetSomeData(ctx)
if err != nil {
return err
}
file, err := os.Create("example.csv")
if err != nil {
return err
}
defer file.Close()
// also file need to be delete
writer := csv.NewWriter(file)
defer writer.Flush()
timestamp := time.Now().UTC().Format("2006-01-02 03:04:05.000000000")
for _, d := range data {
csvRow := []string{
d.ID,
d.Name,
timestamp,
}
err = writer.Write(csvRow)
if err != nil {
log.Printf("error writing data to CSV: %v\n", err)
}
}
source := bigquery.NewReaderSource(file)
source.Schema = bigquery.Schema{
{Name: "id", Type: bigquery.StringFieldType},
{Name: "name", Type: bigquery.StringFieldType},
{Name: "createdAt", Type: bigquery.TimestampFieldType},
}
if _, err = bqClient.LoadCsv(ctx, "tableID", source); err != nil {
return err
}
return nil
}
LoadCSV() 看起來像這樣:
func (c *Client) LoadCsv(ctx context.Context, tableID string, src bigquery.LoadSource) (string, error) {
loader := c.bigQueryClient.Dataset(c.datasetID).Table(tableID).LoaderFrom(src)
loader.WriteDisposition = bigquery.WriteTruncate
job, err := loader.Run(ctx)
if err != nil {
return "", err
}
status, err := job.Wait(ctx)
if err != nil {
return job.ID(), err
}
if status.Err() != nil {
return job.ID(), fmt.Errorf("job completed with error: %v", status.Err())
}
return job.ID(), nil
}
運行此操作后,bigquery 確實創建了架構但沒有資料。如果我要更改os.Create()為os.Open()并且檔案已經存在,則一切正常。就像加載CSV時檔案資料尚未寫入(?)是什么原因?
uj5u.com熱心網友回復:
我在這里看到的問題是您沒有將檔案句柄的游標倒回到檔案的開頭。因此,下一個讀將在端的檔案,并且將一個0位元組讀取。這就解釋了為什么檔案中似乎沒有內容。
https://pkg.go.dev/os#File.Seek可以為您處理。
實際上,Flush不相關,因為您使用相同的檔案句柄讀取檔案而不是寫入檔案,因此即使沒有重繪 ,您也會看到自己寫入的位元組。如果檔案由不同的行程打開或重新打開,則不會出現這種情況。
示范:
package main
import (
"fmt"
"io"
"os"
)
func main() {
f, err := os.CreateTemp("", "data.csv")
if err != nil {
panic(err)
} else {
defer f.Close()
defer os.Remove(f.Name())
}
fmt.Fprintf(f, "hello, world")
fmt.Fprintln(os.Stderr, "Before rewind: ")
if _, err := io.Copy(os.Stderr, f); err != nil {
panic(err)
}
f.Seek(0, io.SeekStart)
fmt.Fprintln(os.Stderr, "\nAfter rewind: ")
if _, err := io.Copy(os.Stderr, f); err != nil {
panic(err)
}
fmt.Fprintln(os.Stderr, "\n")
}
% go run t.go
Before rewind:
After rewind:
hello, world
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/334890.html
標籤:走 谷歌-bigquery
上一篇:創建一個長度為輸入的全域二維切片
