DuckDB の Go クライアントで Google Sheets のデータを SQL で取得する
golangDuckDB は SQL で CSV や JSON、Parquet などを高速に読み書きできる OSS。
$ brew install duckdb
$ duckdb
v1.1.3 19864453f7
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
D SELECT * FROM read_csv_auto('test.csv');
┌───────┬─────────┬─────────┐
│ a │ b │ c │
│ int64 │ varchar │ varchar │
├───────┼─────────┼─────────┤
│ 10 │ aaa │ bbb │
│ 20 │ aaa │ ccc │
│ 30 │ bbb │ ddd │
│ 40 │ bbb │ eee │
└───────┴─────────┴─────────┘
CLI ほか Go や Swift、WASM などのクライアント が実装されており、様々な環境で利用することができる。
package main
import (
"database/sql"
"errors"
"fmt"
"log"
_ "github.com/marcboeker/go-duckdb"
)
func main() {
db, err := sql.Open("duckdb", "")
if err != nil {
log.Fatal(err)
}
defer db.Close()
rows, err = db.Exec(`SELECT * FROM read_csv_auto('test.csv');`)
if err != nil {
log.Fatal(err)
}
for rows.Next() {
var (
a int64
b string
c string
)
err = row.Scan(&a, &b, &c)
if errors.Is(err, sql.ErrNoRows) {
log.Println("no rows")
} else if err != nil {
log.Fatal(err)
}
}
}
/*
10 aaa bbb
20 aaa ccc
30 bbb ddd
40 bbb eee
*/
URL を渡すこともできて、次のようにして公開されている Sheet にアクセスできる。
sheetExportURL := "https://docs.google.com/spreadsheets/export?format=csv&id=..."
rows, err := db.Query(fmt.Sprintf(`SELECT * FROM read_csv_auto('%s');`, sheetExportURL))
DuckDB には extension で機能を拡張する仕組みがある。
D SELECT extension_name, installed, description
FROM duckdb_extensions();
┌──────────────────┬───────────┬────────────────────────────────────────────────────────────────────────────────────┐
│ extension_name │ installed │ description │
│ varchar │ boolean │ varchar │
├──────────────────┼───────────┼────────────────────────────────────────────────────────────────────────────────────┤
│ arrow │ false │ A zero-copy data integration between Apache Arrow and DuckDB │
│ autocomplete │ true │ Adds support for autocomplete in the shell │
│ aws │ false │ Provides features that depend on the AWS SDK │
│ azure │ false │ Adds a filesystem abstraction for Azure blob storage to DuckDB │
│ delta │ false │ Adds support for Delta Lake │
│ excel │ false │ Adds support for Excel-like format strings │
│ fts │ false │ Adds support for Full-Text Search Indexes │
│ httpfs │ false │ Adds support for reading and writing files over a HTTP(S) connection │
│ iceberg │ false │ Adds support for Apache Iceberg │
│ icu │ true │ Adds support for time zones and collations using the ICU library │
│ inet │ false │ Adds support for IP-related data types and functions │
│ jemalloc │ false │ Overwrites system allocator with JEMalloc │
│ json │ true │ Adds support for JSON operations │
│ motherduck │ false │ Enables motherduck integration with the system │
│ mysql_scanner │ false │ Adds support for connecting to a MySQL database │
│ parquet │ true │ Adds support for reading and writing parquet files │
│ postgres_scanner │ false │ Adds support for connecting to a Postgres database │
│ shell │ true │ Adds CLI-specific support and functionalities │
│ spatial │ false │ Geospatial extension that adds support for working with spatial data and functions │
│ sqlite_scanner │ false │ Adds support for reading and writing SQLite database files │
│ substrait │ false │ Adds support for the Substrait integration │
│ tpcds │ false │ Adds TPC-DS data generation and query support │
│ tpch │ false │ Adds TPC-H data generation and query support │
│ vss │ false │ Adds indexing support to accelerate Vector Similarity Search │
├──────────────────┴───────────┴────────────────────────────────────────────────────────────────────────────────────┤
│ 24 rows 3 columns │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
コミュニティの GSheets extension を用いると非公開の Sheet にもアクセスできる。この extension は CREATE SECRET 時に access_token を受け取るか oauth による認証を行い、Secrets Manager に 保存して、read_gsheet が token を取得し、Authorization header に乗せてリクエストする。
D INSTALL gsheets FROM community;
D LOAD gsheets;
D CREATE PERSISTENT SECRET (TYPE gsheet);
D SELECT * FROM read_gsheet(...);
extension と secret が保存されている。
$ ls ~/.duckdb/extensions/v1.1.3/osx_arm64/
gsheets.duckdb_extension
gsheets.duckdb_extension.info
httpfs.duckdb_extension
httpfs.duckdb_extension.info
$ ls ~/.duckdb/stored_secrets/__default_gsheet.duckdb_secret
Go から呼ぶ。
if _, err := db.Exec("LOAD gsheets;"); err != nil {
log.Fatal(err)
}
sheetURL := "https://docs.google.com/spreadsheets/d/.../edit"
rows, err := db.Query(fmt.Sprintf(`SELECT * FROM read_gsheet('%s');`, sheetURL))
if err != nil {
log.Fatal(err)
}