Skip to content

caiolandgraf/pam

 
 

Repository files navigation

Pam logo Pam's Database Drawer bitmap

image

"Pam, the receptionist, has been doing a fantastic job."

Michael Scott: "You know what's amazing? Pam. Pam is amazing. She's got this drawer - not just any drawer - a database drawer. Full of SQL queries. I didn't even know we needed that, but apparently everyone does because they keep asking her for them. 'Pam, I need the users query.' 'Pam, where's that sales report?' And she just opens the drawer and boom. There it is. I think it's the most popular drawer in the entire office. Maybe even in Scranton. Possibly Pennsylvania."


MIT License go badge

A minimal CLI tool for managing and executing SQL queries across multiple databases. Written in Go, made beautiful with BubbleTea

Quick StartConfigurationDatabase SupportDbeeslyFeaturesCommandsTUI NavigationRoadmapContributing

This project is currently in beta, please report unexpected behavior through the issues tab


image Demo

pam-demo

Highlights

  • Query Library - Save and organize your most-used queries
  • Runs in the CLI - Execute queries with minimal overhead
  • Multi-Database - Works with PostgreSQL, MySQL, SQLite, Oracle, SQL Server, ClickHouse and Firebird
  • Table view TUI - Keyboard focused navigation with vim-style bindings
  • In-Place Editing - Update cells, delete rows and edit your SQL directly from the results table
  • Export your data - Export your data as CSV, JSON, SQL, Markdown or HTML tables
  • SQL Dump Import/Export - Full SQL dumps (schema + data) and import from file or stdin

image Quick Start

Installation

Go to the releases page and find the correct version for your system. Download it and make sure the file is executable and moved to a directory in your $PATH.

Go install

Use go to install pam directly

go install github.com/caiolandgraf/pam/cmd/pam@latest

this will put the binary pam in your $GOBIN path (usually ~/go/bin)

Build Manually

Follow these instructions to build the project locally

git clone https://github.com/caiolandgraf/pam

go build -o pam ./cmd/pam

The pam binary will be available in the root project directory

Nix / NixOS (Flake)

Pam is available as a Nix flake for easy installation on NixOS and systems with Nix.

Run directly without installing

nix run github:caiolandgraf/pam

Install to user profile

nix profile install github:caiolandgraf/pam

Enter development shell

nix develop github:caiolandgraf/pam

NixOS System-wide

Add 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 = [
      {
        nixpkgs.config.allowUnfree = true;
        environment.systemPackages = [
          pam.packages.x86_64-linux.default
        ];
      }
    ];
  };
};
}

Then rebuild: sudo nixos-rebuild switch

Home Manager

Add to your home.nix or flake config:

{
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 = [
      {
        nixpkgs.config.allowUnfree = true;
        home.packages = [
          pam.packages.x86_64-linux.default
        ];
      }
    ];
  };
};
}

Then apply: home-manager switch

Note: Oracle support requires allowUnfree = true in your Nix configuration.

Basic Usage

# Create your first connection — interactive TUI (recommended)
pam init

# Or pass arguments directly
pam init mydb postgres "postgresql://user:pass@localhost:5432/mydb"

# Add a saved query
pam add list_users "SELECT * FROM users"

# List your saved queries
pam list queries

# Run it, this opens the interactive table viewer
pam run list_users

# Or run inline SQL
pam run "SELECT * FROM products WHERE price > 100"

Navigating the Table

Once your query results appear, you can navigate and interact with the data:

# Use vim-style navigation or arrow-keys
j/k        # Move down/up
h/l        # Move left/right
g/G        # Jump to first/last row

# Copy data
y          # Yank (copy) current cell
v          # Enter visual mode to select multiple cells and copy with y
x          # Export selected data as csv, tsv, json, sql, markdown or html

# Sort data
f          # Toggle sort on current column
           # In tables list: • default → ↑ ASC → ↓ DESC → • default
           # In regular queries: none → ↑ ASC → ↓ DESC → none

# Edit data directly
u          # Update current cell (opens your $EDITOR)
D          # Delete current row

# Modify and re-run
e          # Edit the query and re-run it

# Exit
q          # Quit back to terminal

image Configuration

Pam stores its configuration at ~/.config/pam/config.yaml.

Row Limit default_row_limit: 1000

All queries are automatically limited to prevent fetching massive result sets. Configure via default_row_limit in config or use explicit LIMIT in your SQL queries.

Column Width default_column_width: 15

Column widths in the table TUI are now dynamic and responsive. They automatically adapt to:

  • The content of your data (sampling up to 100 rows)
  • The available terminal width
  • Column headers and type indicators

The table will:

  • Use the full available terminal width
  • Resize automatically when you change your terminal size
  • Apply intelligent min/max constraints (8-50 characters per column)
  • Distribute extra space proportionally among columns

You can still configure a fallback default_column_width in the config file for edge cases, but the dynamic sizing will take precedence in most scenarios.

Color Schemes color_scheme: "default"

Customize the terminal UI colors with built-in schemes:

Available schemes: default, dracula, gruvbox, solarized, nord, monokai black-metal, black-metal-gorgoroth, vesper, catppuccin-mocha, tokyo-night, rose-pine, terracotta

Each scheme uses a 7-color palette: Primary (titles, headers), Success (success messages), Error (errors), Normal (table data), Muted (borders, help text), Highlight (selected backgrounds), Accent (keywords, strings).


image Database Support

Interactive Setup (recommended)

Run pam init with no arguments to launch the interactive TUI. It will guide you through each field individually and assemble the connection string automatically:

  Connection name  › mydb
  Database type    › postgres  ◀ ▶
  Host             › localhost
  Port             › 5432
  Username         › myuser
  Password         › ••••••
  Database         › mydb

  conn › postgres://myuser:secret@localhost:5432/mydb
  • Port is pre-filled with the default for the selected database type
  • Password is masked by default — press Ctrl+P to toggle visibility
  • The connection string preview updates live as you type
  • For SQLite, only File path is shown (no host/user/password)
  • Press Enter to confirm, Esc to cancel

Examples of init/create commands to start working with different database types

PostgreSQL

pam init pg-prod postgres postgres://myuser:mypassword@localhost:5432/mydb?sslmode=disable

# or connect to a specific schema:
pam init pg-prod postgres postgres://myuser:mypassword@localhost:5432/mydb?sslmode=disable schema-name

MySQL / MariaDB

pam init mysql-dev mysql 'myuser:mypassword@tcp(127.0.0.1:3306)/mydb'

pam init mariadb-docker mariadb "root:MyStrongPass123@tcp(localhost:3306)/dundermifflin"

SQL Server

pam init sqlserver-docker sqlserver "sqlserver://sa:MyStrongPass123@localhost:1433/master"

SQLite

pam init sqlite-local sqlite file:///home/eduardo/dbeesly/sqlite/mydb.sqlite

Oracle

pam init oracle-stg oracle myuser/mypassword@localhost:1521/XEPDB1

# or connect to a specific schema:
pam init oracle-stg oracle myuser/mypassword@localhost:1521/XEPDB1 schema-name

Make sure you have the Oracle Instant Client or equivalent installed in your system

ClickHouse

pam init clickhouse-docker clickhouse "clickhouse://myuser:mypassword@localhost:9000/dundermifflin"

FireBird

pam init firebird-docker firebird user:masterkey@localhost:3050//var/lib/firebird/data/the_office

🐝 Dbeesly

To run containerized test database servers for all supported databases, use the sister project dbeesly

image

image Features

Query Management

Save, organize, and execute your SQL queries with ease.

# Add queries with auto-incrementing IDs
pam add daily_report "SELECT * FROM sales WHERE date = CURRENT_DATE"
pam add user_count "SELECT COUNT(*) FROM users"
pam add employees "SELECT TOP 10 * FROM employees ORDER BY last_name"

# Add parameterized queries with :param|default syntax
pam add emp_by_salary "SELECT * FROM employees WHERE salary > :min_sal|30000"
pam add search_users "SELECT * FROM users WHERE name LIKE :name|P% AND status = :status|active"

# When creating queries with params and not default, pam will prompt you for the param value every time you run the query
pam add search_by_name "SELECT * FROM employees where first_name = :name"

# Run parameterized queries with named parameters (order doesn't matter!)
pam run emp_by_salary --min_sal 50000
pam run search_users --name Michael --status active
# Or use positional args (must match SQL order)
pam run search_users Michael active

# List all saved queries
pam list queries

# Search for specific queries
pam list queries emp    # Finds queries with 'emp' in name or SQL
pam list queries employees --oneline # displays each query in one line

# Run by name or ID
pam run daily_report
pam run 2

# Edit query before running (great for testing parameter values)
pam run emp_by_salary --edit
image

TUI Table Viewer

Navigate query results with Vim-style keybindings, update cells in-place, delete rows and copy data

image

Key Features:

  • Syntax-highlighted SQL display
  • Column type indicators
  • Primary key markers
  • Live cell editing
  • Visual selection mode

Connection Switching

Manage multiple database connections and switch between them instantly.

# List all connections
pam list connections
pam switch production

Display current connection and check if it is reachable

pam status
image

Database Exploration

Explore your database schema and visualize relationships between tables.

# List all tables and views in multi-column format
pam explore

# Query a table directly
pam explore employees --limit 100

# Visualize foreign key relationships
pam explain employees
pam explain employees --depth 2    # Show relationships 2 levels deep
image

Note: The pam explain command is currently a work in progress and may change in future versions.


Editor Integration

Pam uses your $EDITOR environment variable for editing queries and UPDATE/DELETE statements.

image
# Set your preferred editor
export EDITOR=vim
export EDITOR=nano
export EDITOR=code

You can also use the editor to edit queries before running them

# Edit existing query before running
pam run daily_report --edit

# Create and run a new query on the fly
pam run

# Re-run the last executed query
pam run --last

# Edit all queries at once
pam edit queries

Data Import & Export

Export tables as portable SQL dumps with CREATE TABLE + INSERT statements, and import them back into any compatible database.

# ── Export ─────────────────────────────────────────────────────

# Dump all tables to a file (schema + data)
pam export --output=backup.sql

# Dump a single table
pam export --table=users --output=users.sql
pam export users                              # shorthand

# Pipe to stdout (status messages go to stderr, so this is clean)
pam export --table=orders > orders.sql

# Schema only — CREATE TABLE statements, no INSERT
pam export --no-data --output=schema.sql

# Data only — INSERT statements, no CREATE TABLE
pam export --data-only > inserts.sql

# Add DROP TABLE IF EXISTS before each CREATE TABLE
pam export --drop --output=full.sql

# ── Import ─────────────────────────────────────────────────────

# Import from a file
pam import dump.sql

# Read from stdin (pipe-friendly)
cat dump.sql | pam import

# Don't stop on the first error — collect and report all failures
pam import dump.sql --continue-on-error

# Dry run — parse and list every statement without executing
pam import dump.sql --dry-run

# Full migration pipeline between two connections
pam switch staging
pam export --table=users > users.sql
pam switch production
pam import users.sql

SQL output is always written to stdout and status/progress messages to stderr, so redirects like pam export > dump.sql work cleanly without mixing output.


image All Commands

Connection Management

Command Description Example
init Create a new connection via interactive TUI pam init
init <name> <type> <conn-string> [schema] Create connection with arguments pam init mydb postgres "postgresql://..."
switch <name> Switch to a different connection pam switch production
status Show current active connection pam status
list connections List all configured connections pam list connections
ls Shorthand for list connections pam ls
disconnect Disconnect from current database pam disconnect
remove --conn <name> Remove a saved connection pam remove --conn mydb

Query Operations

Command Description Example
add <name> [sql] Add a new saved query pam add users "SELECT * FROM users"
remove <name|id> Remove a saved query pam remove users or pam remove 3
remove --conn <name> Remove a saved connection pam remove --conn mydb
list queries List all saved queries pam list queries
list queries --oneline lists each query in one line pam list -o
list queries <searchterm> lists queries containing search term 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 Edit query before running pam run users --edit
run --last, -l Re-run last executed query pam run --last
run --param run with named params pam run --name Pam

Database Exploration

Command Description Example
explore List all tables and views in multi-column format pam explore
explore <table> [-l N] Query a table with optional row limit pam explore employees --limit 100
explain <table> [-d N] [-c] Visualize foreign key relationships pam explain employees --depth 2

Tables

Command Description Example
tables List all tables in current database pam tables
tables <table> Query a specific table pam tables users
tables --oneline List tables one per line pam tables --oneline

Info

Command Description Example
info tables List all tables from current schema pam info tables
info views List all views from current schema pam info views

Configuration

Command Description Example
edit config Edit main configuration file pam edit config
edit queries Edit all queries for current connection pam edit queries
help [command] Show help information pam help run

Import & Export

Command Description Example
export Dump all tables (schema + data) 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-create Skip CREATE TABLE statements pam export --no-create
export --drop Prepend DROP TABLE IF EXISTS pam export --drop --output=full.sql
export --no-data Schema only, no INSERT statements pam export --no-data --output=schema.sql
export --data-only Data only, no CREATE TABLE pam export --data-only > inserts.sql
import <file> Import a SQL dump from a file pam import dump.sql
import --file=<f> Import with explicit flag pam import --file=dump.sql
import --continue-on-error Keep going after failed statements pam import dump.sql --continue-on-error
import --dry-run Parse statements without executing pam import dump.sql --dry-run

Command Aliases

Many commands have shorter aliases for faster typing:

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 tables List or query tables
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

image TUI Table Navigation

When viewing query results in the TUI, you have full Vim-style navigation and editing capabilities.

Basic Navigation

Key Action
h, Move left
j, Move down
k, Move up
l, Move right
g Jump to first row
G Jump to last row
0, _, Home Jump to first column
$, End Jump to last column
Ctrl+u, PgUp Page up
Ctrl+d, PgDown Page down

Data Operations

Key Action
v Enter visual selection mode
y Copy selected cell(s) to clipboard
Enter Show cell value in detail view (with JSON formatting)
u Update current cell (opens editor)
D Delete current row (requires WHERE clause)
e Edit and re-run query
s Save current query
q, Ctrl+c, Esc Quit table view

Detail View Mode

Press Enter on any cell to open a detailed view that shows the full cell content. If the content is valid JSON, it will be automatically formatted with proper indentation.

In Detail View:

Key Action
, , j, k Scroll through content
e Edit cell content (opens editor with formatted JSON)
q, Esc, Enter Close detail view

When you press e in detail view:

  • The editor opens with the full content (JSON will be formatted)
  • Edit the content as needed
  • Save and close to update the database
  • JSON validation is performed automatically
  • The table view updates with the new value

Visual Mode

Press v to enter visual mode, then navigate to select a range of cells. Press y to copy the selection as plain text, or x to export the selected data as csv, tsv, json, sql insert statement, markdown or html

The copied or exported data will be available in your clipboard


image Roadmap

This project is currently in beta, please report unexpected behavior through the issues tab

v0.1.0 Ryan 📎

  • Multi-database support (PostgreSQL, MySQL, SQLite, Oracle, SQL Server, ClickHouse)
  • Query library with save/edit/remove functionality
  • Interactive TUI with Vim navigation
  • In-place cell updates and row deletion
  • Visual selection and copy (single and multi cell)
  • Syntax highlighting
  • Query editing in external editor
  • Primary key detection
  • Column type indicators
  • Row limit configuration option
  • Info command, list all tables/views in current connection

v0.2.0 - Kelly 👗

  • Program colors configuration option
  • Query parameter with prompt and defaults (e.g., WHERE first_name = :name|Pam)
  • CSV/JSON export for multiple cells
  • Display column types correctly for join queries
  • pam explore and pam explain

v0.3.0 - Jim 👔

  • Shell autocomplete (bash, fish, zsh)
  • Encryption on connection username/password in config file
  • Dynamic column width
  • SQL dump export — pam export [--table=<t>] [--output=<file>] [--drop] [--no-data] [--data-only]
  • SQL dump import — pam import [<file>] [--continue-on-error] [--dry-run]

Contributing

We welcome contributions! Get started with detailed instructions from CONTRIBUTING.md

Thanks a lot to all the contributors:

Acknowledgments

Pam wouldn't exist without the inspiration and groundwork laid by these fantastic projects:

Built with:

  • Bubble Tea - The TUI framework
  • Go standard library and various database drivers

License

MIT License - see LICENSE file for details


Made with 👚 by @caiolandgraf

"I don't think it would be the worst thing if it didn't work out... Wait, can I say that?" - Pam Beesly (definitely NOT about Pam's Database Drawer)

Pam mascot

About

A minimal CLI tool for managing and executing SQL queries across multiple databases. Written in Go, made beautiful with BubbleTea

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Go 98.3%
  • Other 1.7%