bigquery-emulator

goccyMIT活跃维护

用 Go 实现的 BigQuery 本地模拟服务器,让开发和测试无需连接真实 GCP 就能跑 BigQuery 查询。

BigQuery emulator server implemented in Go

v0.8.1发布于 2026-06-13 05:52 UTC1,160star195fork同步于 2026-11-07 07:34 UTC

怎么上手

由 README 提炼,执行前请确认
docker run -it -p 9050:9050 -p 9060:9060 ghcr.io/goccy/bigquery-emulator:latest --project=test
go install github.com/goccy/bigquery-emulator/cmd/bigquery-emulator@latest
硬件要求按 README 说明

README 未说明,仅提到 SQL 后端为纯 Go,无需本地编译步骤

支持 Apple Silicon有 Docker 镜像
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

用 Go 实现的本地 BigQuery 模拟器,无需云项目和凭证即可测试开发

用 Go 实现的 BigQuery 本地模拟服务器,让开发和测试无需连接真实 GCP 就能跑 BigQuery 查询。

核心能力

  • 用 SQLite 做存储,可选内存或文件持久化
  • 启动时从 YAML 文件加载初始数据
  • 支持 GoogleSQL 查询,覆盖约 570 个内置函数
  • 支持 gRPC Storage 读写 API 与流式插入
  • 可作为静态单二进制独立运行,也可用 httptest 同进程启动

容易踩的坑

gRPC 服务默认 9060 端口为明文不加密,Python Storage 客户端需用 insecure_channel 构造 transport,否则 TLS 握手失败;用 DataFrame 下载结果时需设 create_bqstorage_client=False 或指向本地 gRPC 端口;M1 Mac 上用 Docker 可能报警告,需加 --platform linux/x86_64;项目仍为 beta,IAM、行级访问策略、copy job、外部表、快照和 BigQuery ML 尚未实现

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.8.1
  1. v0.8.1最新正式版2026-06-13 · 2026-06-13 05:52 UTC

    Changelog

    • a531d3deb716eaba4972f9afa88e03e2c0f1a1af Bump googlesqlite to v0.3.1 (#489)
  2. v0.8.02026-06-13 · 2026-06-13 02:31 UTC
    查看更新说明

    Changelog

    • 5e2b77fc97d3c9985f5ec1fcf813a45a8f650e27 API correctness: deleteContents, CreateDisposition, default ReadSession stream (#341, #360, #409) (#474)
    • 2e89b4c4595705d73d5278af1d93a96cf03cedf3 Bump googlesqlite to v0.3.0, fix TestStorageWrite race, and unbreak the e2e bq job from a PYTHONPATH leak (#486)
    • 2f5009038c2f7da3a63a4ed46ef9da1b3ddd2599 Fix IN UNNEST(@param) with named ARRAY/STRUCT parameters silently returning no rows (#475)
    • 445539310ecb011961b6ca1088f4b58e616b5422 Fix Storage API issues: nil ReadOptions panic, case-insensitive columns, proto wrapper unwrap (#382, #380, #364) (#473)
    • 95733c0a8fbce3f000d8ed8dbbe2c4507a4131ad Materialize EXPORT DATA statements to GCS (#418) (#476)
    • 0921f7f42c17cdacbac02af82c4da8bb6cd142a8 Register the job in the synchronous jobs.query path (#477)
  3. v0.7.22026-05-19 · 2026-05-19 16:32 UTC
    查看更新说明

    Changelog

    • e8dc89bf30539df0f7e467d11b8194808beed68b Fix COUNT over an empty table (#468) and add multi-client insertAll e2e coverage (#471)
    • 3102d2d1131d8a172de5f212a3732450db663ea9 Improve README intro for first-time visitors (#469)
  4. v0.7.12026-05-19 · 2026-05-19 01:54 UTC
    查看更新说明

    Changelog

    • 2e73d3d705ac166a366472127a9c4b368d5bcd4f Fix a batch of v0.7.0 follow-up bugs (#467)
  5. v0.7.02026-05-18 · 2026-05-18 14:13 UTC
    查看更新说明

    Changelog

    • 283a94d87cc9e77a93a4c2a6285b5fbff6d243bc Cap GoReleaser build parallelism to avoid OOM on the release runner (#466)
    • 7282db96e750c0748913b16752f2b76ec698c33d Fix all open GitHub Security reports (#462)
    • dafbca6c1e55eec0ad21b6f6150c8e458409fcb4 Fix list projects to return NumericId and FriendlyName (#431)
    • 6d8cfcf0eebcc9741f2c513e09bc9ed1c9ba2b1f Import newest discovery document from Google (#424)
    • dec85d4768a8cea910a3a94fff791993d48dfa7f Limit Dependabot to security updates and refresh dependencies (#464)
    • 92f5ee7f4b9a9daf557e4770db537fcd00a7a487 Modernize the release pipeline and fix multi-arch image publishing (#465)
    • d21b248b0fa5d9828cfad8f479c78fa431087249 Refresh README for the googlesqlite backend and add a feature matrix (#461)
    • db5cfcc4b5b6d32e00eb188e88aed87457352003 Reject backtick/backslash in SQL identifiers to close injection vector (#463)
    • 1bffdb5af5d628fc546a349527aba27dfdc634dd Setup multi-arch builds for Docker. (#401)
    • cc2e43183cf68451732f853b8ba4530e2eaa44d1 Switch the SQL backend to googlesqlite and harden BigQuery compatibility (#448)

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    BigQuery Emulator

    build and test GoDoc Sponsor

    The only open-source emulator for Google BigQuery — run a BigQuery-compatible server on your local machine for testing and development, with no cloud project or credentials required.

    Quick start

    $ docker run -it -p 9050:9050 -p 9060:9060 ghcr.io/goccy/bigquery-emulator:latest --project=test
    $ bq --api http://0.0.0.0:9050 query --project_id=test "SELECT 1"
    

    See Install for go install, prebuilt binaries and packages, and How to start the standalone server for the full set of options and client examples.

    Features

    • If you can choose the Go language as BigQuery client, you can launch a BigQuery emulator on the same process as the testing process by httptest .
    • BigQuery emulator can be built as a static single binary and can be launched as a standalone process. So, you can use the BigQuery emulator from programs written in non-Go languages or such as the bq command, by specifying the address of the launched BigQuery emulator.
    • BigQuery emulator utilizes SQLite for storage. You can select either memory or file as the data storage destination at startup, and if you set it to file, data can be persisted.
    • You can load seeds from a YAML file on startup

    Status

    This project is still in beta, but a large part of BigQuery already works from the official client libraries. The multi-client conformance suite (test/e2e) exercises the official Python, Ruby, PHP, Node.js and Java client libraries plus the bq CLI against the emulator over a shared query corpus, and currently passes for every client.

    BigQuery is a large product, so rather than scatter caveats across this README, the emulator's coverage is tracked feature by feature in a single MECE (mutually exclusive, collectively exhaustive) matrix:

    📋 BigQuery feature support matrix

    At a glance, the emulator supports dataset / table / job / tabledata management, GoogleSQL query execution, batch load and extract jobs (including loads from Google Cloud Storage), streaming inserts, the gRPC BigQuery Storage read/write APIs, and logical and materialized views. IAM policy management, row access policies, copy jobs, external tables, table snapshots and BigQuery ML are not implemented yet. See the matrix for the complete, categorized breakdown.

    GoogleSQL

    Query execution is powered by googlesqlite, which implements almost all of GoogleSQL: as of googlesqlite v0.1.0 its spec-driven support matrix reports 523 / 529 GoogleSQL functions and 55 / 59 BigQuery-specific functions implemented — roughly 570 built-in functions — along with 16 / 18 data types. Beyond functions, it also supports:

    • Wildcard tables
    • Templated-argument functions
    • JavaScript UDF

    For the authoritative, per-function and per-type support matrix, see the googlesqlite status.

    Goals

    The goal of this project is to build a server that behaves exactly like BigQuery from the BigQuery client's perspective. To do so, we need to support all features present in BigQuery ( Model API / Connection API / INFORMATION SCHEMA etc.. ) in addition to evaluating GoogleSQL.

    Sponsorship

    This is a personal project. It receives no support of any kind from Google — no sponsorship, no contributions, no promotion.

    For example, Google has had a request for a BigQuery emulator open on its Issue Tracker (issue 129248927) for seven years without taking any action. Unable to watch that any longer, in 2022 I built bigquery-emulator — the only BigQuery emulator in the world — and have maintained it ever since.

    I do not use BigQuery in my own job, however. I simply happen to have the skills to build this, noticed how many people are struggling without it, and so I spend my personal time and money on it. I develop it on my days off and after work, while working full time and maintaining a lot of other OSS, so the time available for this project is limited.

    Because of that, keeping this project alive needs your help. Emulating BigQuery locally brings many benefits to development and can significantly cut development costs. Could you return a small part of those savings to me? I believe doing so leads to a better future for both me and your company. Especially if you are part of a commercial company and could use this project, I'd be glad if you could consider sponsoring me.

    Install

    If Go is installed, you can install the latest version with the following command

    $ go install github.com/goccy/bigquery-emulator/cmd/bigquery-emulator@latest
    

    The SQL backend is pure Go, so installation is an ordinary go install with no native build step.

    You can also download the docker image with the following command

    $ docker pull ghcr.io/goccy/bigquery-emulator:latest
    

    The image is a multi-arch manifest, so the same tag works on both linux/amd64 and linux/arm64.

    You can also download prebuilt binaries (darwin/linux/windows, amd64/arm64) and deb/rpm/apk packages directly from releases.

    Both the release archives and the container image ship a signed GitHub build-provenance attestation. Verify them with the GitHub CLI:

    # release archive
    $ gh attestation verify bigquery-emulator_v0.0.0_linux_amd64.tar.gz --repo goccy/bigquery-emulator
    
    # container image
    $ gh attestation verify oci://ghcr.io/goccy/bigquery-emulator:latest --repo goccy/bigquery-emulator
    

    How to start the standalone server

    If you can install the bigquery-emulator CLI, you can start the server using the following options.

    $ ./bigquery-emulator -h
    Usage:
      bigquery-emulator [OPTIONS]
    
    Application Options:
          --project=        specify the project name
          --dataset=        specify the dataset name
          --port=           specify the http port number. this port used by bigquery api (default: 9050)
          --grpc-port=      specify the grpc port number. this port used by bigquery storage api (default: 9060)
          --log-level=      specify the log level (debug/info/warn/error) (default: error)
          --log-format=     specify the log format (console/json) (default: console)
          --database=       specify the database file if required. if not specified, it will be on memory
          --data-from-yaml= specify the path to the YAML file that contains the initial data
      -v, --version         print version
    
    Help Options:
      -h, --help            Show this help message
    

    Start the server by specifying the project name

    $ ./bigquery-emulator --project=test
    [bigquery-emulator] REST server listening at 0.0.0.0:9050
    [bigquery-emulator] gRPC server listening at 0.0.0.0:9060
    

    If you want to use docker image to start emulator, specify like the following.

    $ docker run -it -p 9050:9050 -p 9060:9060 ghcr.io/goccy/bigquery-emulator:latest --project=test
    
    • If you are using an M1 Mac ( and Docker Desktop ) you may get a warning. In that case please use --platform linux/x86_64 option.

    How to use from bq client

    1. Start the standalone server

    $ ./bigquery-emulator --project=test --data-from-yaml=./server/testdata/data.yaml
    [bigquery-emulator] REST server listening at 0.0.0.0:9050
    [bigquery-emulator] gRPC server listening at 0.0.0.0:9060
    
    • server/testdata/data.yaml is here

    2. Call endpoint from bq client

    $ bq --api http://0.0.0.0:9050 query --project_id=test "SELECT * FROM dataset1.table_a WHERE id = 1"
    
    +----+-------+---------------------------------------------+------------+----------+---------------------+
    | id | name  |                  structarr                  |  birthday  | skillNum |     created_at      |
    +----+-------+---------------------------------------------+------------+----------+---------------------+
    |  1 | alice | [{"key":"profile","value":"{\"age\": 10}"}] | 2012-01-01 |        3 | 2022-01-01 12:00:00 |
    +----+-------+---------------------------------------------+------------+----------+---------------------+
    

    How to use from python client

    1. Start the standalone server

    $ ./bigquery-emulator --project=test --dataset=dataset1
    [bigquery-emulator] REST server listening at 0.0.0.0:9050
    [bigquery-emulator] gRPC server listening at 0.0.0.0:9060
    

    2. Call endpoint from python client

    Create ClientOptions with api_endpoint option and use AnonymousCredentials to disable authentication.

    from google.api_core.client_options import ClientOptions
    from google.auth.credentials import AnonymousCredentials
    from google.cloud import bigquery
    from google.cloud.bigquery import QueryJobConfig
    
    client_options = ClientOptions(api_endpoint="http://0.0.0.0:9050")
    client = bigquery.Client(
      "test",
      client_options=client_options,
      credentials=AnonymousCredentials(),
    )
    client.query(query="...", job_config=QueryJobConfig())
    

    If you use a DataFrame as the download destination for the query results, You must either disable the BigQueryStorage client with create_bqstorage_client=False or create a BigQueryStorage client that references the local grpc port (default 9060).

    https://cloud.google.com/bigquery/docs/samples/bigquery-query-results-dataframe?hl=en

    result = client.query(sql).to_dataframe(create_bqstorage_client=False)
    

    or use a BigQuery Storage client that points at the local gRPC port (see below).

    3. Call the BigQuery Storage API (gRPC) from the python client

    The emulator's gRPC server (default port 9060) speaks plaintext — it does not terminate TLS. The google-cloud-bigquery-storage clients (BigQueryReadClient / BigQueryWriteClient) default to a secure (TLS) channel, so passing only api_endpoint makes the client attempt a TLS handshake against a plaintext server and fail with an error such as:

    E0000 ... ssl_transport_security.cc:... Handshake failed with fatal error
    SSL_ERROR_SSL: error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER
    

    To talk to the emulator you must build the client on top of an insecure gRPC channel via its transport. For the read client:

    import grpc
    from google.cloud import bigquery_storage
    from google.cloud.bigquery_storage_v1.services.big_query_read.transports import (
        BigQueryReadGrpcTransport,
    )
    
    transport = BigQueryReadGrpcTransport(
        channel=grpc.insecure_channel("0.0.0.0:9060"),
    )
    read_client = bigquery_storage.BigQueryReadClient(transport=transport)
    result = client.query(sql).to_dataframe(bqstorage_client=read_client)
    

    For the write client (Storage Write API), do the same with its transport:

    import grpc
    from google.cloud import bigquery_storage
    from google.cloud.bigquery_storage_v1.services.big_query_write.transports import (
        BigQueryWriteGrpcTransport,
    )
    
    transport = BigQueryWriteGrpcTransport(
        channel=grpc.insecure_channel("0.0.0.0:9060"),
    )
    write_client = bigquery_storage.BigQueryWriteClient(transport=transport)
    

    If you use a Go client, pass an insecure gRPC connection with option.WithGRPCConn(grpc.NewClient("0.0.0.0:9060", grpc.WithTransportCredentials(insecure.NewCredentials()))) when constructing storage.NewBigQueryReadClient / NewBigQueryWriteClient.

    Synopsis

    If you use the Go language as a BigQuery client, you can launch the BigQuery emulator on the same process as the testing process.
    Please imports github.com/goccy/bigquery-emulator/server ( and github.com/goccy/bigquery-emulator/types ) and you can use server.New API to create the emulator server instance.

    See the API reference for more information: https://pkg.go.dev/github.com/goccy/bigquery-emulator

    package main
    
    import (
      "context"
      "fmt"
    
      "cloud.google.com/go/bigquery"
      "github.com/goccy/bigquery-emulator/server"
      "github.com/goccy/bigquery-emulator/types"
      "google.golang.org/api/iterator"
      "google.golang.org/api/option"
    )
    
    func main() {
      ctx := context.Background()
      const (
        projectID = "test"
        datasetID = "dataset1"
        routineID = "routine1"
      )
      bqServer, err := server.New(server.TempStorage)
      if err != nil {
        panic(err)
      }
      if err := bqServer.Load(
        server.StructSource(
          types.NewProject(
            projectID,
            types.NewDataset(
              datasetID,
            ),
          ),
        ),
      ); err != nil {
        panic(err)
      }
      if err := bqServer.SetProject(projectID); err != nil {
        panic(err)
      }
      testServer := bqServer.TestServer()
      defer testServer.Close()
    
      client, err := bigquery.NewClient(
        ctx,
        projectID,
        option.WithEndpoint(testServer.URL),
        option.WithoutAuthentication(),
      )
      if err != nil {
        panic(err)
      }
      defer client.Close()
      routineName, err := client.Dataset(datasetID).Routine(routineID).Identifier(bigquery.StandardSQLID)
      if err != nil {
        panic(err)
      }
      sql := fmt.Sprintf(`
    CREATE FUNCTION %s(
      arr ARRAY<STRUCT<name STRING, val INT64>>
    ) AS (
      (SELECT SUM(IF(elem.name = "foo",elem.val,null)) FROM UNNEST(arr) AS elem)
    )`, routineName)
      job, err := client.Query(sql).Run(ctx)
      if err != nil {
        panic(err)
      }
      status, err := job.Wait(ctx)
      if err != nil {
        panic(err)
      }
      if err := status.Err(); err != nil {
        panic(err)
      }
    
      it, err := client.Query(fmt.Sprintf(`
    SELECT %s([
      STRUCT<name STRING, val INT64>("foo", 10),
      STRUCT<name STRING, val INT64>("bar", 40),
      STRUCT<name STRING, val INT64>("foo", 20)
    ])`, routineName)).Read(ctx)
      if err != nil {
        panic(err)
      }
    
      var row []bigquery.Value
      if err := it.Next(&row); err != nil {
        if err == iterator.Done {
            return
        }
        panic(err)
      }
      fmt.Println(row[0]) // 30
    }
    

    Debugging

    If you have specified a database file when starting bigquery-emulator, the file is an ordinary SQLite database and can be inspected with any SQLite tool.

    How it works

    BigQuery Emulator Architecture Overview

    After receiving a GoogleSQL query via the REST API from bq or a client SDK, the googlesqlite driver parses and analyzes the query — using go-googlesql, a GoogleSQL (ZetaSQL) parser and analyzer written in Go — and executes it against an embedded SQLite database.

    Type Conversion Flow

    BigQuery has a number of types that do not exist in SQLite (e.g. ARRAY and STRUCT). In order to handle them in SQLite, googlesqlite encodes all types except INT64 / FLOAT64 / BOOL with the type information and data combination and stores them in SQLite. When using the encoded data, decode the data via a custom function registered with the SQLite driver before use.

    Reference

    Regarding the story of bigquery-emulator, there are the following articles.

    License

    MIT