Skip to main content

Local BigQuery

A BigQuery emulator for development and tests. It serves the BigQuery REST and Storage APIs and runs GoogleSQL on DuckDB, so the official clients work with no project or credentials.

Quick start

docker run -p 9050:9050 -p 9060:9060 -v bigquery:/data ghcr.io/novucs/local-bigquery:0.3.2

Then point a client at http://localhost:9050, without credentials. Any project ID works, and data persists in /data.

Connecting

Python

from google.auth.credentials import AnonymousCredentials
from google.cloud import bigquery

client = bigquery.Client(
    project="local",
    credentials=AnonymousCredentials(),
    client_options={"api_endpoint": "http://localhost:9050"},
)
rows = client.query_and_wait("SELECT 1 AS x")

For faster to_dataframe(), add the Storage Read API, served as plain gRPC on port 9060:

import grpc
from google.cloud import bigquery_storage_v1
from google.cloud.bigquery_storage_v1.services.big_query_read.transports import (
    BigQueryReadGrpcTransport,
)

transport = BigQueryReadGrpcTransport(channel=grpc.insecure_channel("localhost:9060"))
bqstorage = bigquery_storage_v1.BigQueryReadClient(transport=transport)
frame = client.query_and_wait("SELECT 1 AS x").to_dataframe(bqstorage_client=bqstorage)

For SQLAlchemy, pass the client in: create_engine("bigquery://local", connect_args={"client": client}).

Go

client, err := bigquery.NewClient(ctx, "local",
    option.WithEndpoint("http://localhost:9050/bigquery/v2/"),
    option.WithoutAuthentication(),
)

Node.js

import { BigQuery } from "@google-cloud/bigquery";

const bigquery = new BigQuery({ projectId: "local", apiEndpoint: "http://localhost:9050" });
const [rows] = await bigquery.query("SELECT 1 AS x");

Testing with pytest

pip install local-bigquery

This adds pytest fixtures that run the emulator inside the test process. There's no Docker, and it starts in under a second:

  • bigquery_client: a client connected to an emulator shared by the whole test run.
  • bigquery_dataset: a new dataset for each test, deleted afterwards.
  • bigquery_emulator: the emulator's rest_url, grpc_address and project_id.
def test_totals(bigquery_client, bigquery_dataset):
    table = f"{bigquery_dataset.dataset_id}.orders"
    bigquery_client.query_and_wait(f"CREATE TABLE {table} (customer STRING, amount INT64)")
    bigquery_client.insert_rows_json(table, [{"customer": "a", "amount": 2}] * 3)
    rows = bigquery_client.query_and_wait(f"SELECT SUM(amount) AS total FROM {table}")
    assert [row.total for row in rows] == [6]

Features

  • SQL: GoogleSQL functions, DML including MERGE, DDL, scripting, procedures, SQL/JavaScript UDFs, table functions, wildcard tables, INFORMATION_SCHEMA.
  • Tables: partitioning, clustering, constraints, views, materialized views, snapshots, clones, time travel, search and vector indexes.
  • Jobs: query, load, copy and extract, with dry runs, cancellation and sessions.
  • Data: CSV, JSON, Parquet, Avro and ORC loads, and CSV, JSON, Parquet and Avro exports. Also insert_rows_json and the Storage Read and Write APIs.
  • gs://: maps to $DATA_DIR/gcs, or to a GCS emulator set by STORAGE_EMULATOR_HOST.
  • Row access policies: the caller is the service account that signed the request. Signatures aren't checked, so any key works: service_account.Credentials.from_service_account_file("key.json", always_use_jwt_access=True). Unsigned requests run as CALLER.
  • EXTERNAL_QUERY against Postgres at POSTGRES_URI.
  • REPL: local-bigquery repl. Delete all data with local-bigquery reset.

Limitations

  • For test-sized data on one machine. There's no authentication, and IAM policies aren't enforced.
  • Legacy SQL and BigQuery ML functions (ML.PREDICT and so on) aren't supported.
  • A failed statement aborts the whole transaction.
  • STRING(n) and BYTES(n) lengths aren't enforced.
  • Other API methods return 501.

Found a difference from BigQuery? Open an issue.

Configuration

Set these as environment variables, or pass the matching flag to local-bigquery.

Variable Flag Default
BIGQUERY_PORT --port 9050
GRPC_PORT --grpc-port 9060
DATA_DIR --data-dir /data
DEFAULT_PROJECT_ID --project local
DEFAULT_DATASET_ID --dataset local
CALLER user:local-bigquery@localhost
GROUPS {}, e.g. {"user:alice@example.com": ["group:team@example.com"]}
GCS_LOCAL_ROOT $DATA_DIR/gcs
STORAGE_EMULATOR_HOST
POSTGRES_CONNECTION_ID us.default
POSTGRES_URI postgresql://postgres:example@db:5432/postgres

Development

uv run local-bigquery --data-dir /tmp/local-bigquery   # run from source
uv run pytest                                           # run the tests
uv run pytest --endpoint google --project <project>     # run them against real BigQuery

License

MIT

Metadata

Release files for local-bigquery 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for local-bigquery 0.3.2
File Size Uploaded
local_bigquery-0.3.2.tar.gz 222.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for local-bigquery 0.3.2
File Interpreter ABI Platform
local_bigquery-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 484.5 kB

Release files / local_bigquery-0.3.2.tar.gz

Download URL local_bigquery-0.3.2.tar.gz
Size 222.4 kB
Tags Source
SHA-256 checksum
How to use checksums
84de4d779eb1aac1ae9e539666be1edc434d6ab0fc01ffe60be9881e35c9faba
BLAKE2b-256 checksum
How to use checksums
ba22b33cd2b397be486894dff3459a4ebcc3131a3c332ef65e8db0344c0ab063
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / local_bigquery-0.3.2-py3-none-any.whl

Download URL local_bigquery-0.3.2-py3-none-any.whl
Size 262.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
98dba942ea744c86a3c1161383e02a3c001472b1b7beb923fb699137a5ff3d0a
BLAKE2b-256 checksum
How to use checksums
35ffb88ec577373aec57ea36d00a4190c6a1ef10ea2aeb70cae711fead3a395e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.3.2 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page