Skip to main content

duckboard

File-first local SQL workspace for CSV, Parquet, PSV, and JSON — powered by DuckDB.

Load files once, query by name with plain SQL, export results. Terminal-native alternative to spinning up a notebook for quick file questions.

Status: v0.2.1 — available on PyPI.

Install

pip install duckboard

Development install:

git clone https://github.com/OmUniyal/duckboard
cd duckboard
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"

Quickstart

duckboard
duckboard> :load examples/sample.csv as sample
duckboard> SELECT color, COUNT(*) AS n FROM sample GROUP BY 1;
┌────────┬───┐
│ color  │ n │
├────────┼───┤
│ blue   │ 1 │
│ green  │ 1 │
│ red    │ 2 │
└────────┴───┘
(3 rows)
duckboard> :save results.csv
Saved 3 rows to results.csv
duckboard> :quit
Bye.

Supported file formats

Extension Format
.csv, .tsv CSV
.psv PSV (pipe-separated)
.parquet Parquet
.json, .jsonl, .ndjson JSON

REPL commands

Command Description
:load "path" [as name] [--no-header] Load a file as a queryable table. Name defaults to filename stem. Use --no-header if the file has no header row — duckboard will prompt for column names or auto-generate them.
:tables List all loaded tables with format, path, and validation status.
:schema <table> Show column names, types, and nullability for a table.
:save "path" [--csv|--parquet|--json] Save last query result to a file. Format auto-detected from extension; use flag to override.
:unload <table> Remove a loaded table from the session.
:rename_column table old_name new_name Rename a column in a loaded table.
:export_errors table "path" [--csv|--parquet|--json] Export rows that failed validation to a file.
:export_clean table "path" [--csv|--parquet|--json] Export only validated rows to a file.
:pwd Show current working directory.
:clear / :cls Clear the terminal.
:quit / :q / exit / quit / Ctrl+D Exit duckboard.

Data quality

When a CSV or PSV file is loaded, duckboard automatically validates the first 1,000 rows and reports two types of issues:

Structural errors — rows whose field count doesn't match the header:

duckboard> :load "sales.csv" as sales
Loaded 'sales' from sales.csv  (csv)
  1 validation error(s) found. Run 'SELECT * FROM _errors_sales' to inspect.

Type anomalies — rows where a numeric value appears in a predominantly string column (e.g. a number in a gender column).

All errors are stored in _errors_{name} for the duration of the session:

SELECT * FROM _errors_sales;

The :tables command shows an error indicator for affected tables:

┌────────┬────────┬───────────┬────────┐
│ name   │ format │ path      │ errors │
├────────┼────────┼───────────┼────────┤
│ sales  │ csv    │ sales.csv │ [!1]   │
│ orders │ csv    │ orders.csv│ ok     │
└────────┴────────┴───────────┴────────┘

Notes

  • Queries display a maximum of 50 rows in the terminal. Full results are always exported via :save.
  • Large exports (2,000+ rows) prompt for confirmation before writing.
  • On Windows, use forward slashes in paths: :load data/sales.csv not :load data\sales.csv.
  • Multi-line SQL is supported — statements execute on semicolon.
  • Validation runs on CSV and PSV files only. Parquet and JSON validation is planned for v0.3.0.
  • python -m duckboard works as an alternative launch method if the script entry point is unavailable.

Read more

I built a terminal SQL workspace for CSV files — and made it catch bad data automatically — dev.to

Project layout

src/duckboard/
├── __main__.py     # Enables python -m duckboard
├── session.py      # DuckboardSession — owns DuckDB connection + state
├── catalog.py      # Registered file → view mappings + validation
├── repl.py         # Interactive REPL loop
├── commands.py     # All REPL commands
├── formatter.py    # Box-drawing table output for query results
├── cli.py          # CLI entry point
└── exceptions.py   # DuckboardError hierarchy

License

MIT

Metadata

Release files for duckboard 0.2.1

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

Source distribution (sdist)

Source distribution for duckboard 0.2.1
File Size Uploaded
duckboard-0.2.1.tar.gz 18.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for duckboard 0.2.1
File Interpreter ABI Platform
duckboard-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 34.0 kB

Release files / duckboard-0.2.1.tar.gz

Download URL duckboard-0.2.1.tar.gz
Size 18.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e2d09dacad1f576a79559cf3c1247842178c28985f11b176da46213d64485eea
BLAKE2b-256 checksum
How to use checksums
a555a9ba2a4f92362fa1cbd1c5eaf011e1ca9144aceef50729799463190b3425
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.9

Release files / duckboard-0.2.1-py3-none-any.whl

Download URL duckboard-0.2.1-py3-none-any.whl
Size 15.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cc6f16d8077a620c27949312e8f8089ec49a0a869dcbb4269f3471ad3bddfed4
BLAKE2b-256 checksum
How to use checksums
b4293ae4dd4fb79d2ab14d876fb19848a11b6ff339f68ad4e9f2dbc6058b6196
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.9

Release history Release notifications | RSS feed

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.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