select-bq
A SELECT-only BigQuery CLI wrapper for agentic use (e.g. with Cursor). Wraps the official bq CLI and enforces:
- SELECT-only: Queries are validated via SQL AST parsing—no DML, DDL, scripting,
EXECUTE IMMEDIATE, or hidden CTEs that could modify data. - Allowlist: Optional config restricts queries to allowed tables (string patterns
project.dataset.table). Empty or missing allowlist = no restriction. - Audit logging: All queries (including rejections) are logged to a YAML file with timestamps.
Install
pip install select-bq
Requires the Google Cloud SDK (bq CLI) and gcloud auth login.
Setup
Create a config file .select-bq.yaml in your project root:
# Where to log queries (default: select-bq-queries.yaml in current dir)
log_path: select-bq-queries.yaml
# Optional allowlist. Omit or leave empty to allow all tables.
# When present, only these patterns can be queried (three dot-separated parts).
allowlist:
- my-gcp-project.analytics.events
- my-gcp-project.analytics.* # all tables in this dataset
- my-gcp-project.*.* # entire project
- my-gcp-project.analytics.onecrm-* # glob on table name (fnmatch)
log_path— Path for the query log (default:select-bq-queries.yaml). Use an absolute path to log outside the project.allowlist— List of stringsproject.dataset.table. Use*for a full segment wildcard; useprefix*/*suffixstyle globs in a segment when you need pattern matching. Omit to allow all tables.
To use a different config path: select-bq query --config ./my-config.yaml "SELECT 1".
To use an external allowlist file:
log_path: select-bq-queries.yaml
allowlist_path: allowlist.yaml
Usage
# Run a SELECT query (same as bq query, but validated)
select-bq query "SELECT 1"
select-bq query "SELECT * FROM project.dataset.table LIMIT 10" --format=pretty
# Query from file
select-bq query -f query.sql
# Custom config
select-bq query --config ./my-config.yaml "SELECT * FROM my_table"
# Use Standard SQL (default) or legacy SQL
select-bq query --use_legacy_sql=false "SELECT 1"
select-bq query --use_legacy_sql=true "SELECT 1"
# All bq query flags are passed through (format, project_id, etc.)
select-bq query --format=pretty --project_id=my-project "SELECT 1"
Query Log
Logged to log_path (default select-bq-queries.yaml):
queries:
- timestamp: "2025-03-09T12:00:00.000000+00:00"
query: "SELECT 1"
success: true
- timestamp: "2025-03-09T12:01:00.000000+00:00"
query: "INSERT INTO t VALUES (1)"
success: false
error: "Statement type 'Insert' is not allowed. Only SELECT queries are permitted."
Security
- AST parsing: Uses sqlglot with BigQuery dialect. Only
SELECTstatements are allowed;INSERT,UPDATE,DELETE,CREATE,DROP,EXECUTE IMMEDIATE,DECLARE,SET, and similar are rejected. - Allowlist: When configured, only tables matching the allowlist patterns can be queried (e.g.
dataset.*for all tables in a dataset). - No eval/exec: Validation is purely structural—no dynamic execution of user input.
Cursor Integration
Add to your project's Cursor rules or AGENTS.md:
Use `select-bq query "SELECT ..."` when querying BigQuery. Do not use raw `bq` for queries.
Publishing
To build and publish to PyPI:
pip install build twine
python -m build
twine upload dist/*
Metadata
Release files for select-bq 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| select_bq-0.3.0.tar.gz | 10.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| select_bq-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.7 kB
Release files / select_bq-0.3.0.tar.gz
| Download URL | select_bq-0.3.0.tar.gz |
|---|---|
| Size | 10.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
529d630e17da34e9c5fc3079ac9e071643fe87d22a9723a596b056e0d478105b
|
|
BLAKE2b-256 checksum How to use checksums |
a89198ce64f7deba1bf6c3e3c4a215cabc9db3e6c403f547ea0c42adc3f09e55
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.0
|
Release files / select_bq-0.3.0-py3-none-any.whl
| Download URL | select_bq-0.3.0-py3-none-any.whl |
|---|---|
| Size | 10.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d568f1a308af92caabac1d2b17d2d259d4611fdc269f77d5ebfc929a4597719f
|
|
BLAKE2b-256 checksum How to use checksums |
fd5230d351bfb3d649213b33531278aad087d4a8ac04cca1fdd54e87fcbac237
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.0
|