Skip to main content

Auto-generate CLIs from SQLite databases. Tables become subcommands, columns become filter flags.

Project description

sqlflag

Auto-generate a CLI from any SQLite database. Tables become subcommands, columns become filter flags, column types determine the available operators. No configuration. Point it at a .db file and the CLI appears.

$ sqlflag mydb.sqlite repos --language python --stars gt:50 --order -stars --limit 10

Install

pip install sqlflag

Quick start

# Inspect the schema
$ sqlflag mydb.sqlite schema
Table                   Rows    Columns
repos                   142     8
events                  1203    5
active_repos (view)     87      8

# See per-column operators for a table
$ sqlflag mydb.sqlite schema repos
Column          Type        Operators
name            TEXT        not, contains
language        TEXT        not, contains
stars           INTEGER     not, gt, lt
created_at      DATETIME    not, since, before
...

# Query with typed operator prefixes
$ sqlflag mydb.sqlite repos --language python --stars gt:50 --format json
$ sqlflag mydb.sqlite events --timestamp since:30d
$ sqlflag mydb.sqlite repos --language python --language go   # IN clause
$ sqlflag mydb.sqlite repos --language python --stars gt:50 --any   # OR across flags

# Raw SQL when flags aren't enough
$ sqlflag mydb.sqlite sql "SELECT r.name, COUNT(e.id) FROM repos r JOIN events e ON e.repo_id = r.id GROUP BY r.id"

Shell completion

The standout feature: completion that knows your schema and (optionally) your data.

Install completion

# bash
eval "$(sqlflag --install-completion bash)"

# zsh
eval "$(sqlflag --install-completion zsh)"

# fish
sqlflag --install-completion fish | source

Persist by appending to your shell config (e.g. sqlflag --install-completion bash >> ~/.bashrc).

What gets completed

$ sqlflag mydb.sqlite re<TAB>
refresh_log  repos

$ sqlflag mydb.sqlite repos --lan<TAB>
--language  --languages

$ sqlflag mydb.sqlite repos --stars <TAB>
gt:  lt:  not:  null

$ sqlflag mydb.sqlite repos --timestamp <TAB>
since:  before:  not:  null

$ sqlflag mydb.sqlite repos --columns name,<TAB>
name,language  name,stars  name,description ...

Operator prefixes are type-aware: numeric columns offer gt: / lt:, text columns offer contains:, datetime columns offer since: / before:. The closed set of seven operators is documented per-column via sqlflag <db> schema <table>.

Opt-in: distinct-value completion

For discoverability, sqlflag can tab-complete actual column values. Off by default because it runs SQL on every TAB press:

export SQLFLAG_COMPLETE_VALUES=1

$ sqlflag mydb.sqlite repos --language P<TAB>
PHP  Python

Bounded by cardinality: columns with more than SQLFLAG_VALUE_COMPLETE_MAX distinct values (default 100) skip value completion to keep TAB latency predictable.

Operators

Every column flag accepts [op:]value. The seven-operator set is closed; unknown prefixes fall through to literal equality.

Prefix SQL Use case
(bare) = / IN Default. Multiple values produce IN (...).
not: != not:null produces IS NOT NULL.
gt: > Numeric only (but not enforced).
lt: < Numeric only (but not enforced).
contains: LIKE '%val%' Substring match. Safe: no user wildcards.
since: >= Relative (30d, 6h, 2w, 3mo, 1y) or ISO-8601 dates.
before: < Same date parsing as since:.

Plus the literal null for IS NULL queries.

Composing filters

  • Conditions within a single flag always AND together: --stars gt:5 --stars lt:100 means stars > 5 AND stars < 100.
  • Conditions across different flags AND together by default: --language python --stars gt:50.
  • Add --any to OR across flags: --language python --stars gt:50 --any.

Output formats

Format When Notes
table Default when stdout is a TTY Rich-rendered with automatic column widths.
json Default when stdout is piped Newline-delimited JSON. Preserves types.
csv Opt-in via --format csv Header row plus data rows.

Auto-detection can be overridden with --format.

Reserved flags

Every table subcommand also exposes these, in addition to its per-column filter flags:

Flag Purpose
--any OR-compose conditions across flags.
--order COL ORDER BY. Prefix with - for DESC: --order -stars. Multiple allowed.
--limit N LIMIT.
--columns A,B,C SELECT only these columns.
--format F Output format (table, json, csv, plus plugin formats).
--search TEXT Full-text search (only on tables with an FTS5 index).

If a column name collides with a reserved flag, the column is silently omitted from flag generation and remains reachable via sql.

Read-only by design

All database access opens SQLite with mode=ro URI. Even the sql escape hatch cannot write. sqlflag is for exploration, not mutation.

Programmatic API

sqlflag exposes two Python classes for consumers who want filter compilation without the Click layer (e.g. MCP tool handlers, web services, test fixtures):

from sqlflag import QueryEngine

engine = QueryEngine("mydb.sqlite")
rows = engine.query(
    "repos",
    filters={"language": ["python"], "stars": ["gt:50"]},
    conjunction="all",
    order=["-stars", "name"],
    limit=10,
    columns=["name", "language", "stars"],
)

For wide tables, SqlFlag accepts a default_columns argument that overrides SELECT * with a curated display subset. --columns at the CLI level still overrides this.

from sqlflag import SqlFlag

app = SqlFlag(
    "mydb.sqlite",
    default_columns={
        "repos": ["name", "language", "stars", "description"],
    },
)

Links

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sqlflag-0.6.1.tar.gz (31.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sqlflag-0.6.1-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

File details

Details for the file sqlflag-0.6.1.tar.gz.

File metadata

  • Download URL: sqlflag-0.6.1.tar.gz
  • Upload date:
  • Size: 31.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for sqlflag-0.6.1.tar.gz
Algorithm Hash digest
SHA256 bfdbad7ffe237a2761e4a7accc5e0913f23d5ab61f603b57ba05b3e427b1bce8
MD5 e03e375f7da6da4794e79905672db422
BLAKE2b-256 7a695ef8f991fd699343e11696dca590da5ea5bc46bc378d258eb484bb3203b5

See more details on using hashes here.

File details

Details for the file sqlflag-0.6.1-py3-none-any.whl.

File metadata

  • Download URL: sqlflag-0.6.1-py3-none-any.whl
  • Upload date:
  • Size: 17.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for sqlflag-0.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1631f53738f121a6e2a60a7f0ae55e2c77998c309e8f5ffd3fa2d5ae592e547e
MD5 1bd837431dcef9ae79964bb5b23d7a16
BLAKE2b-256 1c9e454770290792eb8995aecad4d89bdd6bee8d3f87c033cd3d3359174cb67b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page