hsql
hsql is your agent's favorite SQL client. It the headless CLI for
Harlequin, and shares the same config and query engine,
with an interface optimized for agents, scripts, and automations.
[!TIP] This README contains a small subset of the docs available at harlequin.sh.
If you already use Harlequin and know about adapters and config files, jump ahead to Running hsql.
Installing hsql
hsql is packaged with Harlequin, so if you already use Harlequin, hsql is already installed.
Otherwise, you can install hsql directly. hsql is a Python program, and there are many ways to install and run it. We strongly recommend using uv:
-
Install uv. From a POSIX shell, run:
curl -LsSf https://astral.sh/uv/install.sh | sh
Or using Windows Powershell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
-
Install hsql as a tool using
uv:uv tool install hsql
This command will install hsql into an isolated environment and add it to your PATH so you can easily run the executable.
Installing Database Adapters
hsql can connect to dozens of databases using adapter plug-ins. Adapters are distributed as their own Python packages that need to be installed into the same environment as hsql and harlequin.
For a list of known adapters provided either by the Harlequin maintainers or the broader community, see the adapters page.
The adapter docs also include installation instructions (installing an adapter with Harlequin also installs it for hsql). Some adapters can be installed as Harlequin extras, like postgres. If you used uv to install hsql directly, you can add adapter packages using --with:
uv tool install hsql --with harlequin-postgres
You can install multiple extras:
uv tool install hsql --with harlequin-postgres --with harlequin-mysql
Running hsql
Once hsql is installed, you run it from the command line. If you have used psql or the duckdb CLI, hsql will feel familiar, but hsql has the major advantage that is works with most databases and provides the same interface and produces the same output, regardless of the connected database. This means you (and your agent) can learn one tool, instead of several. In your shell, all hsql commands take the same form:
hsql [OPTIONS] [CONN_STR]
where [OPTIONS] is 0 or more pairs of the form --[option-name] [option-value], and [CONN_STR] is 0 or more connection strings. [OPTIONS] are composed of both hsql options and adapter options. For a full list of options, run hsql with the --help option:
hsql --help
Using hsql with DuckDB
hsql defaults to using its DuckDB database adapter, which ships with hsql and includes the full DuckDB in-process database.
Run a query against an in-memory DuckDB session, run hsql and pass in a query with the -c option:
$ hsql -c "select 1"
1
---
1
(1 row)
To query one or more DuckDB database files, pass in relative or absolute paths as connection strings (hsql will create DuckDB databases if they do not exist):
$ hsql "path/to/duck.db" -tAc "select count(*) from orders"
42
Using hsql with SQLite and Other Adapters
hsql also ships with a SQLite3 adapter. To use that adapter, you specify the --adapter sqlite option. Like DuckDB, you can open an in-memory SQLite database by omitting the connection string:
$ hsql --adapter sqlite -c "select 'Ted' as author"
author
--------
Ted
(1 row)
You can query one or more SQLite database files by passing in their paths as connection strings; note that the --adapter option has a short alias, -a:
$ hsql -a sqlite "path/to/sqlite.db" -c "select * from users"
id | name
----+---------
1 | Ted
2 | Patrick
(2 rows)
Other adapters work the same way; for example, Postgres:
$ hsql -a postgres "postgresql://example.com/postgres:5432" -c "select * from invoices"
[!TIP] You should use Profiles to keep credentials out of your shell history. For more information, keep reading or see the docs on config files.
Configuring hsql and Using Profiles
hsql supports a number of options for setting the query limit, configuring output formats, and defining connection parameters. Options can be passed as command-line flags, or read from config files. Config files store configurations under separate profiles, so you can easily switch between databases by reading from different profiles with the -P option:
$ hsql -P prod -c "select count(*) from orders" --csv
$ hsql -P dev -c "select * from users" --vertical --limit 5
$ hsql -P warehouse -c "..." --parquet -o invoices.pq
Data Layouts and File Formats
hsql supports all of the following formats for displaying and writing data:
- table
- markdown (alias: md)
- vertical
- csv
- tsv
- json
- jsonl (alias: ndjson)
- parquet
- orc
- feather (alias: arrow)
- none (suppresses output)
You can select a format with the --format <name> or using the shorthand --<name>, so these are equivalent: --format csv, --csv.
Some layouts can present the results from multiple queries. Others will raise an error and exit with code 2 if multiple queries are executed.
Additionally, for any layout, pass --stats to print summary info as JSON to stderr:
$ hsql -c "select 1" --format none --stats
{"status":"ok","statements":1,"rows":1,"truncated":false,"limit":500,"elapsed_ms":1,"columns":[{"name":"1","type":"#"}]}
Scripting with hsql
[!WARNING] To make hsql safe and efficient for agents, by default hsql applies a 500-row limit to all queries. To remove this limit, use
--limit -1or setlimit = -1in your profile. If limits truncate data, hsql will print a warning on stderr; we recommend that you do NOT suppress or redirect that message so do NOT use hsql with2>/dev/null.
hsql can write data to files, either with the -o option or by piping output (hsql only writes data to stdout; other messages go to stderr):
$ hsql -P prod --limit -1 -c "select * from users" --parquet -o "users.pq"
$ hsql -P prod --limit -1 -c "select * from users" --csv > users.csv
hsql can execute multiple statements in one invocation, and supports several methods for doing so:
- Pass
-cmultiple times - Include multiple queries, separated by
;, in one-coption - Pass one or more .sql files with
-f, with multiple statements in each - Use
--resultsto define which queries output data to stdout - Use
--on-errorto eitherstoporcontinueif one or more queries produces an error.
In other words, this works:
$ hsql -P prod --limit -1 --format md --results all --on-error stop \
-f ./setup.sql \
-c "select count(*) from raw_table" \
-f ./build-models.sql \
-c "select count(*) from modeled_table"
hsql's exit codes are meaningful and stable:
- 0: Success
- 1: Query error
- 2: Usage/config error
- 3: Connection error
- 4: Timeout
- 130: Interrupted
You can also use --stats and jq together to error on a truncated query:
hsql --limit -1 -c "select 1" --csv -o data.csv --stats 2>&1 | jq -e '.truncated | not' > /dev/null
Keep Reading at harlequin.sh
Visit harlequin.sh for an overview of features and full documentation.
Getting Help
To view all command-line options for Harlequin and all installed adapters, after installation, simply type:
hsql --help
GitHub Discussions are a good place to ask questions, request features, and say hello.
GitHub Issues are the best place to report bugs.
Sponsoring Harlequin and hsql
Please consider sponsoring Harlequin's author, so he can continue to dedicate time to hsql.
Contributing
Thanks for your interest in Harlequin! Harlequin and hsql are primarily maintained by Ted Conbeer, but he welcomes all contributions!
Please see CONTRIBUTING.md for more information.
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 hsql-2.9.0.tar.gz.
File metadata
- Download URL: hsql-2.9.0.tar.gz
- Upload date:
- Size: 7.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f03514e79db7fc47e916be35114c02016b6457bcc3c887b24502c9eb33c40be0
|
|
| MD5 |
0e837c25fd2c6c9fc637a816c44e72bd
|
|
| BLAKE2b-256 |
287b36f4e2228fdf48b4c9268b416bb64424d4a1e8d53ed5345af7290e8c0401
|
Provenance
The following attestation bundles were made for hsql-2.9.0.tar.gz:
Publisher:
publish.yml on tconbeer/harlequin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hsql-2.9.0.tar.gz -
Subject digest:
f03514e79db7fc47e916be35114c02016b6457bcc3c887b24502c9eb33c40be0 - Sigstore transparency entry: 2473109449
- Sigstore integration time:
-
Permalink:
tconbeer/harlequin@88c2ca3e345dcf793802d8c9320687ec26efcd0e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/tconbeer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@88c2ca3e345dcf793802d8c9320687ec26efcd0e -
Trigger Event:
pull_request
-
Statement type:
File details
Details for the file hsql-2.9.0-py3-none-any.whl.
File metadata
- Download URL: hsql-2.9.0-py3-none-any.whl
- Upload date:
- Size: 5.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d3b411c3c8b239944d2da9f653810f181f4c1877a3cb2e6ebab0ab8a4974957
|
|
| MD5 |
6c2bf1f31d58a4098c888ddfbfd5abfa
|
|
| BLAKE2b-256 |
3d25aadb315be3f89ff2c3b79449c4c40a84d769568f862e0cb08860d976c332
|
Provenance
The following attestation bundles were made for hsql-2.9.0-py3-none-any.whl:
Publisher:
publish.yml on tconbeer/harlequin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hsql-2.9.0-py3-none-any.whl -
Subject digest:
3d3b411c3c8b239944d2da9f653810f181f4c1877a3cb2e6ebab0ab8a4974957 - Sigstore transparency entry: 2473109527
- Sigstore integration time:
-
Permalink:
tconbeer/harlequin@88c2ca3e345dcf793802d8c9320687ec26efcd0e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/tconbeer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@88c2ca3e345dcf793802d8c9320687ec26efcd0e -
Trigger Event:
pull_request
-
Statement type: