Skip to main content

Shoveler: A desktop SQL workbench for DuckDB

Project description

Shoveler - A DuckDB Workbench

A minimal desktop SQL workbench for DuckDB, built with Python and PySide6.

Named after the Australasian shoveler - a species of "dabbling duck" - in honor of both the database's name and the app's purpose.

Setup (uv)

git clone https://github.com/mrmatho/shoveler
cd shoveler
uv sync

uv sync creates a .venv, installs all dependencies including the dev group, and respects uv.lock if it exists. Run it again after pulling changes.

Running

uv run python -m shoveler

Testing

uv run pytest

Configuration layout

Shoveler now keeps most theme and UI configuration out of the widget classes.

  • Theme stylesheets live in src/shoveler/assets/themes/ as .qss files.
  • Structured configuration lives in src/shoveler/config/.
  • theme.py loads and normalizes app themes.
  • syntax.py contains SQL highlighting keywords and per-theme editor colors.
  • ui.py contains shared UI constants such as status colors and path thresholds.
  • text.py contains user-facing labels, tooltips, dialog text, and status message helpers.

When adding a new theme, update both the .qss assets and the relevant per-theme values in src/shoveler/config/ so editor syntax, status colors, and other theme-aware UI elements stay in sync.

Usage

  • Open File — connect to an existing .duckdb or .db file (green indicator)
  • New In-Memory — scratch database; data is lost when closed (amber indicator)
  • File > Save Database As... — save current database state to a .duckdb file
  • Checkpoint — flush the write-ahead log to disk (file databases only)
  • F5 or Ctrl+Enter — run query
  • Select part of your SQL to run only that selection
  • Double-click a table name in the schema panel to insert it into the editor
  • View > Syntax highlighting — toggle SQL highlighting on or off; enabled by default and remembered between launches
  • View > Zoom — increase, decrease, or reset font size for the editor and results panel
    • Editor: Ctrl+=, Ctrl+-, Ctrl+0
    • Results: Ctrl+Shift+=, Ctrl+Shift+-, Ctrl+Shift+0

Documentation (Phase 1)

Basic user docs are available in the docs/ folder:

Publish with GitHub Pages

For a simple setup:

  1. Go to repository Settings > Pages.
  2. Under Build and deployment, set Source to Deploy from a branch.
  3. Choose branch main and folder /docs.
  4. Save.

GitHub Pages will publish the docs automatically from the docs/ directory.

Building a standalone Windows executable

The project includes shoveler.spec with the correct PyInstaller configuration. Use this rather than running pyinstaller with flags directly — the spec handles a non-obvious issue with DuckDB's compiled extension.

uv run pyinstaller shoveler.spec

Output is in dist/Shoveler/. Distribute that folder as a zip.

Building and publishing desktop binaries with GitHub Actions

This repo includes a release workflow at .github/workflows/desktop-release.yml.

  • Trigger: push a tag like v1.2.0 (or run manually with workflow_dispatch).
  • Build matrix: Windows, macOS, Linux.
  • Output artifacts:
    • Shoveler-windows-x64.zip
    • Shoveler-macos-universal.zip
    • Shoveler-linux-x64.tar.gz
  • Release publish: on tag pushes, artifacts are attached automatically to the GitHub Release.

Release steps

  1. Update version/changelog as needed.
  2. Create and push a version tag:
git tag v1.2.0
git push origin v1.2.0
  1. Wait for the Desktop Release workflow to finish.
  2. Open the matching GitHub Release and verify all three artifacts are attached.

Why --onedir and not --onefile? --onefile extracts everything to a temp directory on every launch, which makes startup noticeably slow for a PySide6 app. --onedir is faster and easier to debug if something goes wrong.

Known PyInstaller issue with DuckDB: DuckDB's compiled core (_duckdb.pyd on Windows) lives outside the duckdb/ package directory. PyInstaller does not find it automatically. The spec file uses collect_all('duckdb') which handles this correctly. If you ever regenerate the spec from scratch, make sure this is included or the packaged app will fail to start.

Extending

Feature Where to add it
More export formats Add menu items in ResultsPanel._show_export_menu() — raw data is in _last_rows / _last_columns
Results table badges Update ResultsPanel._populate_table() and keep export using _last_rows / _last_columns only; badge text comes from QueryResult.column_types

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

shoveler-0.2.2.tar.gz (110.2 kB view details)

Uploaded Source

Built Distribution

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

shoveler-0.2.2-py3-none-any.whl (90.8 kB view details)

Uploaded Python 3

File details

Details for the file shoveler-0.2.2.tar.gz.

File metadata

  • Download URL: shoveler-0.2.2.tar.gz
  • Upload date:
  • Size: 110.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shoveler-0.2.2.tar.gz
Algorithm Hash digest
SHA256 9cc666a4a31772c8658e3d3116180c7f3e640b41088c6173ab3f03b4159d9166
MD5 d6c607a032f7cbd9218b76d08318a90c
BLAKE2b-256 0c04acf12f407f92a4ec1a1b4ba1dfd17f1364707724ac5f7668d80a230b2d4a

See more details on using hashes here.

Provenance

The following attestation bundles were made for shoveler-0.2.2.tar.gz:

Publisher: python-publish.yml on mrmatho/shoveler

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file shoveler-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: shoveler-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 90.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shoveler-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a9b67e3039c71d3d4e1a9442b9dac1f8e29acaa5641ca5f7824ea9bc030f6542
MD5 0768f7c112280b71e70ad34f20596107
BLAKE2b-256 5501dad09e0600a6ea0aaa4126dccbbf69941b9a9fc5be635364a30f0c65cc5e

See more details on using hashes here.

Provenance

The following attestation bundles were made for shoveler-0.2.2-py3-none-any.whl:

Publisher: python-publish.yml on mrmatho/shoveler

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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