- Update Cargo.toml targets to include x86_64-pc-windows-msvc - Update README with pre-built binaries section - All 5 platforms now supported: macOS ARM/x86, Linux ARM/x86, Windows x86
140 lines
4.7 KiB
Markdown
140 lines
4.7 KiB
Markdown
# notion-sql
|
|
|
|
`notion-sql` is a Rust CLI for running SQL-style statements against Notion databases through the official Notion REST API.
|
|
|
|
It parses real SQL with `sqlparser`, introspects the target Notion database schema, and translates supported CRUD statements into typed Notion API calls.
|
|
|
|
## Install
|
|
|
|
Homebrew releases are configured through `cargo-dist`:
|
|
|
|
```bash
|
|
brew install KofTwentyTwo/tap/notion-sql
|
|
```
|
|
|
|
From source:
|
|
|
|
```bash
|
|
cargo install --path .
|
|
```
|
|
|
|
## Pre-built Binaries
|
|
|
|
Pre-built binaries are available for all major platforms:
|
|
|
|
- **macOS**: ARM64 (Apple Silicon) and x86_64
|
|
- **Linux**: ARM64 and x86_64
|
|
- **Windows**: x86_64 (MSVC)
|
|
|
|
Download from the [GitHub Releases](https://github.com/KofTwentyTwo/notion-sql/releases) page.
|
|
|
|
## Authentication
|
|
|
|
Create a Notion internal integration, copy its integration secret, and expose it as `NOTION_TOKEN`:
|
|
|
|
```bash
|
|
export NOTION_TOKEN="ntn_..."
|
|
```
|
|
|
|
Share each target Notion database with that integration. Notion only returns databases and pages that the integration can access.
|
|
|
|
## Notion API Version
|
|
|
|
`v0.1.0` intentionally pins `Notion-Version: 2022-06-28` and uses Notion's legacy database endpoints. This keeps the first release focused on the existing database query, page create, page update, and page trash APIs.
|
|
|
|
Notion's `2025-09-03` API introduces data sources and deprecates the older database query endpoint for clients that opt into that version. Databases with multiple data sources may not work with `v0.1.0`; migration to data source endpoints is planned for a later release.
|
|
|
|
## Database Names And IDs
|
|
|
|
The SQL table name can be either:
|
|
|
|
- A Notion database ID, with or without dashes.
|
|
- A friendly database name.
|
|
|
|
Friendly names are resolved with the Notion search endpoint. If no database matches, or multiple databases match, `notion-sql` exits with a clear candidate list.
|
|
|
|
## Usage
|
|
|
|
```bash
|
|
notion-sql --list-databases
|
|
notion-sql "SELECT Name, Status FROM Tasks WHERE Status='Done'"
|
|
notion-sql "SELECT COUNT(*) FROM Tasks WHERE Status='Done'"
|
|
notion-sql "SELECT * FROM Tasks WHERE Priority >= 2 ORDER BY Due ASC LIMIT 10"
|
|
notion-sql "INSERT INTO Tasks (Name, Status) VALUES ('New task', 'To Do')" --apply
|
|
notion-sql "UPDATE Tasks SET Status='Archived' WHERE Priority='Low'" --apply
|
|
notion-sql "DELETE FROM Tasks WHERE Status='Done'" --apply
|
|
notion-sql "DELETE FROM Tasks WHERE Status='Done'" --apply --progress
|
|
```
|
|
|
|
Mutating statements are dry-run by default. Add `--apply` to write changes.
|
|
|
|
Applied `UPDATE` and `DELETE` statements require a `WHERE` clause unless `--force-all` is passed. Use `--force-all` only for intentional full-database mutations.
|
|
|
|
Use `--progress` for long-running queries or mutations. Progress is written to stderr so stdout remains usable for tables, JSON, and CSV.
|
|
|
|
Output formats for `SELECT`:
|
|
|
|
```bash
|
|
notion-sql "SELECT Name, Status FROM Tasks" --json
|
|
notion-sql "SELECT Name, Status FROM Tasks" --csv
|
|
notion-sql --list-databases --json
|
|
```
|
|
|
|
## Supported SQL
|
|
|
|
Supported statements:
|
|
|
|
- `SELECT <cols|*> FROM <db> [WHERE ...] [ORDER BY col [ASC|DESC]] [LIMIT n]`
|
|
- `SELECT COUNT(*) FROM <db> [WHERE ...]`
|
|
- `INSERT INTO <db> (col1, col2) VALUES (v1, v2), ...`
|
|
- `UPDATE <db> SET col=val[, col2=val2 ...] [WHERE ...]`
|
|
- `DELETE FROM <db> [WHERE ...]`
|
|
|
|
Supported `WHERE` operators:
|
|
|
|
- `=`, `!=`, `>`, `<`, `>=`, `<=`
|
|
- `LIKE`, mapped to `equals`, `starts_with`, `ends_with`, or `contains` for supported wildcard shapes
|
|
- `IN (...)`, mapped to a Notion `or` filter
|
|
- `IS NULL`, `IS NOT NULL`
|
|
- Nested `AND` and `OR`
|
|
|
|
Supported Notion property types:
|
|
|
|
- `title`
|
|
- `rich_text`
|
|
- `select`
|
|
- `status`
|
|
- `multi_select`
|
|
- `number`
|
|
- `checkbox`
|
|
- `date`
|
|
|
|
Unsupported SQL features fail clearly rather than being guessed. Examples: joins, aggregates beyond `COUNT(*)`, group-by, subqueries, aliases, arbitrary expressions in projections, unsupported `LIKE` wildcard shapes, and unsupported Notion property types in `SELECT *`.
|
|
|
|
## Development
|
|
|
|
```bash
|
|
cargo fmt
|
|
cargo clippy --all-targets --all-features -- -D warnings
|
|
cargo test
|
|
cargo build --release
|
|
```
|
|
|
|
The risky code paths are covered by unit tests:
|
|
|
|
- SQL statement extraction from `sqlparser` ASTs.
|
|
- SQL `WHERE` expression translation to Notion filters.
|
|
- SQL literal coercion into typed Notion property payloads.
|
|
|
|
## Release Automation
|
|
|
|
Release automation is handled by `dist` 0.32.0.
|
|
|
|
- Branch pushes and PRs run CI.
|
|
- Pushes to `develop`, `release/*`, `rc/*`, and `main` also upload branch build artifacts.
|
|
- Version tags matching `vX.Y.Z` create production GitHub Releases and publish the Homebrew formula.
|
|
- Version tags matching `vX.Y.Z-rc.N` create GitHub prereleases for release candidates.
|
|
- Homebrew formulas publish to `KofTwentyTwo/homebrew-tap`, which requires the `HOMEBREW_TAP_TOKEN` repository secret.
|
|
|
|
See [RELEASING.md](RELEASING.md) for the full flow.
|