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.0 — data quality milestone. 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.csvnot: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.
Project layout
src/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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file duckboard-0.2.0.tar.gz.
File metadata
- Download URL: duckboard-0.2.0.tar.gz
- Upload date:
- Size: 18.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2668d9403875d104824793e40a7a2db8d57adcf64d34e6518d070a00f6b38c1b
|
|
| MD5 |
407fbce9c74df19139f75c91cbad96c6
|
|
| BLAKE2b-256 |
25657106dbdbf3a46c80e73de53c8e1942dd9aa4f9ba0121c8e29859eda86105
|
File details
Details for the file duckboard-0.2.0-py3-none-any.whl.
File metadata
- Download URL: duckboard-0.2.0-py3-none-any.whl
- Upload date:
- Size: 14.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc83827186bc31d5588fcc2bf626d7105e9c883a9d05364f6fb946b1eaa58962
|
|
| MD5 |
fa16ffa9f5ea3d14f0e37d8fac06afb9
|
|
| BLAKE2b-256 |
c0c45f7219a2fae219cec414e6d8a38a6cf993f06922821ed4c46aef2589871b
|