| name | database |
| category | data |
| description | Query and manage SQLite, PostgreSQL, and MySQL databases from the command line. Use when the user asks to run SQL queries, inspect database schemas, create or alter tables, import or export data, manage indexes, analyze query performance with EXPLAIN, back up or restore databases, or perform CRUD operations via sqlite3, psql, or mysql CLI tools.
|
| license | MIT |
| compatibility | Requires sqlite3, psql, or mysql CLI tools depending on the database engine |
| metadata | {"author":"zeph","version":"1.0"} |
Database CLI Operations
Quick Reference
| Action | SQLite | PostgreSQL | MySQL |
|---|
| Connect | sqlite3 db.sqlite | psql -U user -d dbname | mysql -u user -p dbname |
| List databases | .databases | \l | SHOW DATABASES; |
| List tables | .tables | \dt | SHOW TABLES; |
| Describe table | .schema tablename | \d tablename | DESCRIBE tablename; |
| Quit | .quit | \q | \q or exit |
| Run file | .read file.sql | \i file.sql | source file.sql |
SQLite (sqlite3)
Connection and Configuration
sqlite3 mydb.sqlite
sqlite3 -readonly mydb.sqlite
sqlite3 mydb.sqlite "SELECT * FROM users;"
sqlite3 mydb.sqlite < queries.sql
sqlite3 mydb.sqlite ".read queries.sql"
sqlite3 mydb.sqlite -header -column "SELECT * FROM users;"
sqlite3 mydb.sqlite -json "SELECT * FROM users;"
sqlite3 mydb.sqlite -csv "SELECT * FROM users;"
sqlite3 mydb.sqlite -markdown "SELECT * FROM users;"
Dot Commands
.help
.tables
.tables %user%
.schema
.schema users
.indexes
.indexes users
.headers on
.mode column
.width 20 10 30
.timer on
.dbinfo
.dump
.dump users
.import file.csv users
.output result.txt
.output stdout
.changes on
.eqp on
Schema Operations
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE,
created_at TEXT DEFAULT (datetime('now'))
);
ALTER TABLE users ADD COLUMN role TEXT DEFAULT 'user';
ALTER TABLE users RENAME TO app_users;
CREATE INDEX idx_users_email ON users(email);
CREATE UNIQUE INDEX idx_users_name ON users(name);
DROP INDEX idx_users_email;
ANALYZE;
CRUD Operations
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com'), ('Carol', 'carol@example.com');
SELECT * FROM users WHERE role = 'admin' ORDER BY name LIMIT 10;
SELECT name, COUNT(*) as cnt FROM orders GROUP BY name HAVING cnt > 5;
UPDATE users SET role = 'admin' WHERE email = 'alice@example.com';
DELETE FROM users WHERE created_at < datetime('now', '-1 year');
INSERT OR REPLACE INTO users (id, name, email) VALUES (1, 'Alice', 'alice@new.com');
INSERT INTO users (name, email) VALUES ('Alice', 'alice@new.com')
ON CONFLICT(email) DO UPDATE SET name = excluded.name;
Import and Export
sqlite3 -header -csv mydb.sqlite "SELECT * FROM users;" > users.csv
sqlite3 -json mydb.sqlite "SELECT * FROM users;" > users.json
sqlite3 mydb.sqlite <<'EOF'
.mode csv
.import users.csv users
EOF
sqlite3 mydb.sqlite .dump > backup.sql
sqlite3 newdb.sqlite < backup.sql
sqlite3 mydb.sqlite ".backup backup.sqlite"
Query Analysis
EXPLAIN QUERY PLAN SELECT * FROM users WHERE email = 'alice@example.com';
EXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';
PRAGMA integrity_check;
PRAGMA page_count;
PRAGMA page_size;
PRAGMA table_info(users);
PRAGMA foreign_key_check;
PRAGMA journal_mode=WAL;
VACUUM;
PostgreSQL (psql)
Connection
psql -U postgres -d mydb
psql -h localhost -p 5432 -U myuser -d mydb
psql "postgresql://user:password@host:5432/dbname?sslmode=require"
psql -U postgres -d mydb -c "SELECT * FROM users;"
psql -U postgres -d mydb -f queries.sql
psql -U postgres -d mydb --csv -c "SELECT * FROM users;"
psql -U postgres -d mydb -t -A -c "SELECT count(*) FROM users;"
Meta-Commands
\l -- List all databases
\c dbname -- Connect to database
\dt -- List tables in current schema
\dt public.* -- List tables in public schema
\dt+ users -- Table details with size
\d users -- Describe table (columns, types, constraints)
\d+ users -- Extended description (storage, stats)
\di -- List indexes
\di+ idx_users_email -- Index details
\dn -- List schemas
\df -- List functions
\dv -- List views
\du -- List roles/users
\dp users -- Show table privileges
\x -- Toggle expanded display (vertical rows)
\timing -- Toggle query timing display
\i file.sql -- Execute SQL file
\o output.txt -- Send output to file
\o -- Reset output to terminal
\! command -- Execute shell command
\e -- Edit query in $EDITOR
\g -- Execute last query again
\s -- Show command history
\pset format csv -- Set output format (csv, html, latex, wrapped)
Schema Inspection
SELECT schemaname, tablename,
pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename))
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC;
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = 'users'
ORDER BY ordinal_position;
SELECT indexname, indexdef
FROM pg_indexes
WHERE tablename = 'users';
SELECT conname, conrelid::regclass, confrelid::regclass
FROM pg_constraint
WHERE contype = 'f' AND conrelid = 'users'::regclass;
SELECT pid, usename, datname, state, query
FROM pg_stat_activity
WHERE state = 'active';
Backup and Restore
pg_dump -U postgres mydb > backup.sql
pg_dump -U postgres -Fc mydb > backup.dump
pg_dump -U postgres --schema-only mydb > schema.sql
pg_dump -U postgres --data-only mydb > data.sql
pg_dump -U postgres -t users mydb > users.sql
pg_dumpall -U postgres > all_databases.sql
psql -U postgres mydb < backup.sql
pg_restore -U postgres -d mydb backup.dump
pg_restore -U postgres -d mydb -t users backup.dump
Query Analysis
EXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT * FROM users WHERE email = 'alice@example.com';
SELECT relname, n_live_tup, n_dead_tup, last_vacuum, last_autovacuum
FROM pg_stat_user_tables;
SELECT indexrelname, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes
WHERE schemaname = 'public';
ANALYZE users;
ANALYZE;
SELECT query, calls, mean_exec_time, total_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
MySQL (mysql)
Connection
mysql -u root -p
mysql -u myuser -p mydb
mysql -h hostname -P 3306 -u myuser -p mydb
mysql -u root -p -e "SELECT * FROM users;" mydb
mysql -u root -p mydb < queries.sql
mysql -u root -p -N -B -e "SELECT count(*) FROM users;" mydb
Meta-Commands
SHOW DATABASES;
USE mydb;
SHOW TABLES;
SHOW TABLE STATUS;
DESCRIBE users;
SHOW CREATE TABLE users;
SHOW INDEX FROM users;
SHOW PROCESSLIST;
SHOW VARIABLES LIKE '%max%';
SHOW STATUS LIKE 'Threads%';
Backup and Restore
mysqldump -u root -p mydb > backup.sql
mysqldump -u root -p mydb | gzip > backup.sql.gz
mysqldump -u root -p --no-data mydb > schema.sql
mysqldump -u root -p mydb users orders > tables.sql
mysqldump -u root -p --all-databases > all.sql
mysql -u root -p mydb < backup.sql
gunzip < backup.sql.gz | mysql -u root -p mydb
Query Analysis
EXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';
EXPLAIN FORMAT=JSON SELECT * FROM users WHERE email = 'alice@example.com';
ANALYZE TABLE users;
CHECK TABLE users;
OPTIMIZE TABLE users;
SHOW INDEX FROM users;
Common SQL Patterns
SELECT * FROM items ORDER BY id LIMIT 20 OFFSET 40;
SELECT status, COUNT(*) as cnt FROM orders GROUP BY status ORDER BY cnt DESC;
SELECT u.name, o.total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.created_at > '2024-01-01';
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE total > 100);
WITH active_users AS (
SELECT * FROM users WHERE last_login > '2024-01-01'
)
SELECT * FROM active_users WHERE role = 'admin';
SELECT name, department, salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) as rank
FROM employees;
SELECT
COUNT(*) as total,
SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active,
SUM(CASE WHEN status = 'inactive' THEN 1 ELSE 0 END) as inactive
FROM users;
Important Notes
- Always back up before destructive operations (DROP, DELETE, TRUNCATE, ALTER)
- Use transactions for multi-statement changes:
BEGIN; ... COMMIT; (or ROLLBACK;)
- Prefer
EXPLAIN ANALYZE over EXPLAIN to see actual vs estimated row counts
- For SQLite, use WAL mode (
PRAGMA journal_mode=WAL) for concurrent read/write
- For PostgreSQL, use
\x for wide tables to get vertical output
- For MySQL, add
\G at the end of a query for vertical output
- Use
-t (tuples only) and -A (unaligned) in psql for scriptable output
- Never store passwords in command-line arguments; use
.pgpass (psql) or .my.cnf (mysql)
- Use parameterized queries in scripts to prevent SQL injection