A minimal CLI tool for managing and executing SQL queries across multiple databases. Written in Go, made beautiful with BubbleTea. Filed, labeled, and ready when you need it.
Quick Start β’ Configuration β’ Commands β’ Keybindings β’ Features β’ Completion β’ Databases β’ Roadmap β’ Contributing
π¨ Sticky Note: This project is currently in beta β please report unexpected behavior through the Issues tab.
|
π INTEROFFICE MEMO To: Everyone running queries From: Pam Beesly, Receptionist & DBA Subject: Please use the drawer. I organized it myself. Status: π‘ Beta β file unexpected behavior in Issues |
π OFFICE DIRECTORY |
ββββββββββββββββββββββββββββββββ β DUNDER MIFFLIN β’ SCRANTON β β FILED β AUTHORIZED β β ββββββββββββββββββββββββββββββββ
"I have a system. Every query has a name, every name has a drawer, every drawer has a label. It's not complicated, it's just how I do things." β Pam Beesly, Scranton Branch Receptionist & Unofficial DBA
PAM (Pam's Database Drawer) is a keyboard-first CLI tool for saving, organizing, and running SQL queries across multiple databases. Think of it as a filing cabinet for your SQL β instead of hunting through terminal history or a dozen .sql files, you pam add, pam list, and pam run. The interactive TUI table viewer lets you explore results, edit cells in-place, export data, and visualize schema relationships, all without leaving the terminal.
- Query Library β Save, label, and organize queries like a well-maintained filing cabinet; search by name or content
- Multi-Database β PostgreSQL, MySQL/MariaDB, SQLite, Oracle, SQL Server, ClickHouse, Firebird, DuckDB, and Snowflake
- Interactive TUI β Vim-style keyboard navigation in a beautiful BubbleTea table viewer
- In-Place Editing β Update cells, delete rows, and edit SQL directly from the results table
- Interactive Shell β
pam shell/pam replfor a persistent SQL REPL with history, multi-line input, and meta-commands - Flexible Export β
pam run --format <csv|json|tsv|html|sql|markdown>streams results to stdout, pipe-friendly - Edit Before Run β
pam run --edit/-eopens the query in$EDITORbefore executing - Repeat Last Query β
pam run --last/-lre-runs the last executed query without retyping - Visual Line Mode β
Vselects entire rows;vselects cell ranges β both copyable withy - Export Full Table β
Xexports the entire result set to clipboard in your chosen format - Full-Text Search β
/searches cell contents;fsearches column headers;n/Ncycles matches - Row Marking β
mmarks rows for bulk operations;Ddeletes all marked rows in one round-trip - Inline Cell Edit β
eedits a cell value in-place;Eedits the query and reruns it - Connection Management β
pam remove --connection <name>removes a saved connection - Config Editor β
pam configopens the config file in$EDITOR - SQL Import β
pam import <file>imports SQL dumps;pam exportcreates them - Table Query Shortcut β
pam query --table=<name>for quick table access - Enhanced Explain β
pam explain --depth <n>visualizes FK relationships up to N levels deep - Shell Completion β
pam completion --installwrites completion scripts to the standard path automatically pam tables/\dtβ list tables directly from the interactive shell- Environment Variable Expansion β use
${MY_VAR}in connection strings; PAM expands them at runtime - Database Exploration β browse schema, visualize foreign key relationships with
pam exploreandpam explain - Parameterized Queries β
:param|defaultsyntax; pass values with--paramflags or positional args
See Features for details and examples
| Database | Type String | Notes |
|---|---|---|
| PostgreSQL | postgres |
Schema selection supported |
| MySQL / MariaDB | mysql / mariadb |
|
| SQLite | sqlite |
Local file-based |
| Oracle | oracle |
Schema selection supported |
| SQL Server | sqlserver |
|
| ClickHouse | clickhouse |
|
| Firebird | firebird |
|
| DuckDB | duckdb |
CSV/JSON file queries; requires CGO |
| Snowflake | snowflake |
Keypair authentication supported |
See connection init examples in Database Support
Set up your desk at reception in under 2 minutes.
# Create your first connection (PostgreSQL example)
pam init mydb postgres "postgresql://user:pass@localhost:5432/mydb"
# Use environment variables in connection strings β PAM expands them at runtime
pam init mydb postgres "postgresql://${DB_USER}:${DB_PASS}@localhost:5432/mydb"
# Add a saved query
pam add list_users "SELECT * FROM users"
# List your saved queries
pam list queries
# Run it β opens the interactive table viewer
pam run list_users
# Or run inline SQL
pam run "SELECT * FROM products WHERE price > 100"
# Export results without opening the TUI
pam run list_users --format csv > users.csv
pam run list_users --format json
# Start an interactive SQL shell
pam shellGo to the releases page and download the binary for your system. Make sure it is executable and in a directory on your $PATH.
Go install
go install github.com/caiolandgraf/pam/cmd/pam@latestThis puts the pam binary in your $GOBIN path (usually ~/go/bin).
Build Manually
git clone https://github.com/caiolandgraf/pam
go build -o pam ./cmd/pamThe pam binary will be available in the project root directory.
DuckDB requires CGO and is included in the default build. To build without DuckDB:
CGO_ENABLED=0 go build -o pam ./cmd/pamNix / NixOS (Flake)
PAM is available as a Nix flake for easy installation on NixOS and systems with Nix.
nix run github:caiolandgraf/pamnix profile install github:caiolandgraf/pamnix develop github:caiolandgraf/pamAdd to your flake-based configuration.nix or flake.nix:
{
description = "My NixOS config";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
pam.url = "github:caiolandgraf/pam";
};
outputs = { self, nixpkgs, pam, ... }: {
nixosConfigurations.myHostname = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
{
environment.systemPackages = [
pam.packages.x86_64-linux.default
];
}
];
};
};
}Then rebuild: sudo nixos-rebuild switch
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nix-unstable";
pam.url = "github:caiolandgraf/pam";
};
outputs = { self, nixpkgs, pam, ... }: {
homeConfigurations."username" = {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
modules = [
{
home.packages = [
pam.packages.x86_64-linux.default
];
}
];
};
};
}Then apply: home-manager switch
Arch (AUR) - Unofficial
An unofficial AUR package is available at: pam-bin
See Commands for the full command reference and database init examples.
| Command | Description | Example |
|---|---|---|
init <name> <type> <conn> |
Create a new database connection | pam init mydb postgres "postgresql://..." |
use / switch <name> |
Switch active connection | pam use production |
status |
Show current connection info | pam status |
list connections |
List all configured connections | pam list connections |
remove --connection <name> |
Remove a saved connection | pam remove --connection dev4 |
| Command | Description | Example |
|---|---|---|
add <name> [sql] |
Save a new query | pam add users "SELECT * FROM users" |
remove <name|id> |
Remove a saved query | pam remove users |
list queries |
List all saved queries | pam list queries |
list queries --oneline |
One query per line | pam list -o |
list queries <term> |
Search queries by name or SQL | pam list employees |
run <name|id|sql> |
Execute a query | pam run users or pam run 2 |
run |
Create and run a new query | pam run |
run --edit / -e |
Edit query before running | pam run users --edit |
run --last / -l |
Re-run last executed query | pam run --last |
run --format <fmt> |
Output as csv/json/tsv/html/sql/markdown | pam run users --format json |
run --param |
Run with named parameters | pam run emp --name Michael |
shell / repl |
Interactive SQL REPL with history | pam shell |
| Command | Description | Example |
|---|---|---|
explore |
List all tables and views | pam explore |
explore <table> [-l N] |
Query a table with optional row limit | pam explore employees --limit 100 |
explain <table> |
Visualize foreign key relationships | pam explain employees |
explain <table> -d N |
FK relationships up to depth N | pam explain employees --depth 2 |
tables |
Open tables in the TUI results view | pam tables |
query --table=<name> |
Quick table query in TUI | pam query --table=employees |
| Command | Description | Example |
|---|---|---|
config |
Edit config file in $EDITOR |
pam config |
edit |
Edit all queries for current connection | pam edit |
edit <name|id> |
Edit a single named query | pam edit 3 |
import <file> |
Import a SQL dump from a file | pam import dump.sql |
export |
Dump all tables to stdout | pam export > backup.sql |
export --table=<t> |
Dump a single table | pam export --table=users |
export --output=<f> |
Write dump to a file | pam export --output=dump.sql |
export --no-data |
Schema only (no INSERT statements) | pam export --no-data |
export --data-only |
Data only (no CREATE TABLE) | pam export --data-only > inserts.sql |
export --drop |
Prepend DROP TABLE IF EXISTS | pam export --drop --output=full.sql |
completion --install |
Install shell completion scripts | pam completion --install |
help [command] |
Show help information | pam help run |
| Alias | Full Command | Description |
|---|---|---|
use |
switch |
Switch active connection |
save |
add |
Save a new query |
delete |
remove |
Remove a saved query or connection |
ls |
list connections |
List all connections |
t, explore |
tables |
List or query tables |
tv |
table-view |
Inspect and edit table structure |
test |
status |
Show current connection |
clear, unset |
disconnect |
Disconnect from database |
repl |
shell |
Interactive SQL REPL |
See Keybindings for the full reference.
Once your query results appear you can navigate, edit, and export without leaving the TUI:
# Navigation (Vim-style)
j / k Move down / up
h / l Move left / right
g / G Jump to first / last row
0 / $ Jump to first / last column
Ctrl+u/d Page up / down
# Copy & export
y Yank (copy) current cell
v Visual selection mode (cell range)
V Visual line mode (full rows)
x Export selection (csv/tsv/json/sql/markdown/html)
X Export the entire table
# Edit data
e Edit cell value in-place
E Edit query and re-run
m Mark / unmark row for bulk ops
D Delete all marked rows (or current row)
# Search
/ Search cell contents (n / N to cycle)
f Search column headers (; / , to cycle)
# Other
Enter Detail view (JSON-formatted)
s Save current query
? Toggle keybindings help
q / Esc Quit table view
PAM provides dynamic tab completion for bash, zsh, and fish β automatically including your saved queries and connections.
# Install to the standard path for your shell (recommended)
pam completion --install
# Or manually:
echo 'eval "$(pam completion bash)"' >> ~/.bashrc # Bash
echo 'eval "$(pam completion zsh)"' >> ~/.zshrc # Zsh
pam completion fish > ~/.config/fish/completions/pam.fish # FishSee Shell Completion
Row limits, column widths, color schemes, and UI visibility options are configured at ~/.config/pam/config.yaml.
default_row_limit: 1000
default_column_width: 15
color_scheme: "dracula" # dracula, gruvbox, catppuccin-mocha, tokyo-night, nord, rose-pine, ...
ui_visibility:
query_name: true # Show query name header
query_sql: true # Show SQL query display
type_display: true # Show column type indicators
key_icons: true # Show primary key (βΏ) and foreign key (β) icons
footer_cell_content: true # Show current cell preview in footer
footer_stats: true # Show row/col count and position in footer
footer_keymaps: true # Show keybindings help in footerOpen and edit the config directly with:
pam configSee Configuration
"I have a lot of questions. Number one: how dare you ship without tests." β Dwight Schrute (probably)
- Snowflake database support with keypair authentication
- DuckDB improvements (CSV/JSON file queries, improved driver)
- Environment variable expansion in connection strings (
${MY_VAR}) - Interactive SQL REPL (
pam shell/pam repl) with history, multi-line, meta-commands -
pam run --format <csv|json|tsv|html|sql|markdown>β pipe-friendly export -
pam run --edit/-eβ open query in editor before running -
pam run --last/-lβ repeat last executed query - Visual line mode (
Vkey) - Export full table (
Xkey) -
pam remove --connection <name>β remove saved connections -
pam configβ edit config file in$EDITOR -
pam import <file>β import SQL dumps -
pam query --table=<name>β quick table query - Enhanced
pam explain --depth <n>β N-level FK visualization - Shell completion with
--installflag (writes to standard paths) -
pam tables/\dtin interactive shell - Full-text search in table view (
/) and column header search (f) - Row marking (
m) and multi-row delete (D) - Inline cell edit (
e) and edit+rerun (E)
- Configurable keybinds
- Migrate to Bubble Tea v2
- Return more info on exec statements (INSERT, UPDATE, DELETE row counts)
- Homebrew custom tap and nixpkgs entry
- More options to encrypt data in the config file
PAM ships a SKILL.md file in the repo root β a simple reference for AI coding agents (Claude Code, Copilot, etc.) to use PAM non-interactively. It covers safe commands, format flags, parameterized queries, and which commands to avoid (TUI/editor). Point your agent at it if you want it to run SQL queries as part of an automated workflow.
We welcome contributions! See CONTRIBUTING.md for detailed instructions.
"We keep it like a Dunder Mifflin memo: concise, kind, and well-labeled."
Thanks to all contributors:
PAM builds on these fantastic projects:
- naggie/dstask β elegant CLI design patterns and file-based data storage
- DeprecatedLuar/better-curl-saul β a simple and genius approach to CLI tooling
- eduardofuncao/squix β upstream project whose features were merged into PAM
- dbeaver β the OG database management tool
Built with Bubble Tea and the Go standard library.
