{"id":13596069,"url":"https://github.com/muhmud/qsh","last_synced_at":"2026-01-16T19:56:22.803Z","repository":{"id":43366283,"uuid":"311418189","full_name":"muhmud/qsh","owner":"muhmud","description":"shell-based query tool","archived":false,"fork":false,"pushed_at":"2024-02-10T19:33:16.000Z","size":2691,"stargazers_count":165,"open_issues_count":0,"forks_count":3,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-11-06T18:46:25.506Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/muhmud.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-09T17:43:22.000Z","updated_at":"2024-08-23T16:50:59.000Z","dependencies_parsed_at":"2024-08-01T16:40:48.650Z","dependency_job_id":"aa3c9f1a-211b-441c-928f-a2c48bccf654","html_url":"https://github.com/muhmud/qsh","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muhmud%2Fqsh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muhmud%2Fqsh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muhmud%2Fqsh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muhmud%2Fqsh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/muhmud","download_url":"https://codeload.github.com/muhmud/qsh/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248049854,"owners_count":21039282,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T16:02:07.281Z","updated_at":"2026-01-16T19:56:22.774Z","avatar_url":"https://github.com/muhmud.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# qsh\nQuery SHell - improved querying from your terminal\n\n![QSH](images/qsh-querying.gif)\n\nCurrently supports:\n* `sqlite3` (3.37+)\n* `mysql`\n* `psql`\n* `sqlcmd` (for `mssql`)\n* `sqlcl` (for `oracle`)\n* `mclient` (for `monetdb`)\n\nThere is also a generic mode, which can potentially be used with other tools not on this list. The generic mode can be used with non-database tools as well, like the `redis-cli`, REPLs and even shells, such as `bash`. See the [usage](https://github.com/muhmud/qsh/#generic-mode) section below for more details.\n\n## Prerequisites\n\nYou'll need to install \u0026 use [tmux](https://github.com/tmux/tmux), which is needed to manage the split panes. It should be available from your package manager. Installing [jq](https://github.com/stedolan/jq) and `tree` would also be a good idea. For the generic mode, you will need `rlwrap` and `perl`.\n\nFor better viewing of SQL results, the [pspg](https://github.com/okbob/pspg) pager is recommended (ensure you have the latest version), however, you could also use `less -SinFX`. When displaying results, qsh will try to make a sensible choice, however, you can instead explicitly choose a pager. For generic mode, `bat` can also work well.\n\nTo format SQL statements, you will need python 3 and [sqlparse](https://github.com/andialbrecht/sqlparse).\n\n**Note: If you have issues, make sure your local install of `qsh` is fully [up-to-date](https://github.com/muhmud/qsh/#updating).**\n\n## Setup\n\nClone this repository to your home:\n\n```bash\n$ git clone https://github.com/muhmud/qsh.git ~/.qsh\n```\n\nAnd then add the `~/.qsh/bin` directory to your `PATH`.\n\nYou now just need to setup the editor you want to use for writing SQL statements, which will be triggered from your SQL client tool. If you want to, and it's recommended, you can setup a keyboard shortcut for this in your tmux config. This will give you the same consistent shortcut for starting the editor from any tool.\n\nThe following example does this for `Alt-q`:\n\n```\n# qsh\nbind-key -n M-q run-shell ~/.qsh/bin/qsh-start\n```\n\nYou can currently use either `vim`/`nvim` or `micro`. Whichever you choose, make sure your `QSH_EDITOR` or `EDITOR`/`VISUAL` environment variable is set appropriately.\n\n### vim/nvim\n\n#### vim-plug\n\n```\nPlug 'muhmud/qsh', { 'dir': '~/.qsh', 'branch': 'main', 'rtp': 'editors/vim' }\n```\n\n#### packer\n\n```\n{ \"~/.qsh/editors/vim\", as = \"Qsh\" }\n```\n\nThe default key mappings can be found [here](https://github.com/muhmud/qsh/blob/main/editors/vim/plugin/qsh.vim#L24-L95). You can disable them by setting `g:qsh_enable_key_mappings` to `0`.\n\nYou can add custom key mappings like this:\n\n```\nautocmd Filetype sql call QshCustomSqlKeyMappings()\nfunction QshCustomSqlKeyMappings() \n   ...\nendfunction\n```\n\n### Micro\n\nThe [micro](https://micro-editor.github.io/) plugin can be installed by executing the following:\n\n```bash\n$ mkdir -p ~/.config/micro/plug \u0026\u0026 cp -r ~/.qsh/editors/micro ~/.config/micro/plug/qsh\n```\n\nThe following key mappings, or similar, can be added to `~/.config/micro/bindings.json`:\n\n```\n\"Alt-g\": \"command:QshExecute\",\n\"Alt-G\": \"command:QshExecute '^---$' 0\",\n\"Alt-e\": \"command:QshExecuteSelection\",\n\"Alt-y\": \"command:QshExecuteAll\",\n\"Alt-d\": \"command:QshExecuteNamedScript 'describe'\",\n\"Alt-r\": \"command:QshExecuteNamedScript 'select-some'\",\n\"Alt-v\": \"command:QshExecuteScript\",\n\"Alt-i\": \"command:QshExecuteSnippet\",\n\"Alt-t\": \"command:QshExecuteNamedSnippet 'format'\",\n\"Alt-p\": \"command:QshSetUnsetPrefix\"\n```\n\n## Usage\n\nFrom within a `tmux` session, prefix the invocation of your SQL client with `qsh`:\n\n```\n$ qsh psql\n```\n\nThis will setup your SQL client environment appropriately. Now, trigger the editor using the command for your environment. For `mysql`, this would be `\\e;`, and for `psql`, `\\e` or if you setup a keyboard shortcut in your tmux config, as described above, you could use that also. Alternatively, use the `-s` option to startup the editor automatically.\n\nYou should see the editor pane created, where you can now type in queries. A default SQL file is created for you, however, you could open up any other file you need to.\n\n**Note: For `sqlcl`, you would start the editor by using `@qsh`**\n\n### Generic Mode\n\nIf you invoke a tool that `qsh` does not know about, it will go into generic mode and will attempt to give you a usable querying experience, so you shouldn't need to do anything differently.\n\n![Generic](images/qsh-generic.gif)\n\nIf your terminal looks messed up when the tool starts, try to use the REPL mode by specifying the `-r` option:\n\n```\n$ qsh -r redis-cli\n```\n\nYou can also use the `-f` option to change the extension of the file opened up in the editor. This can be useful to enable language/domain specific features for the tool you are using. Setting this value to something that isn't `sql` implicitly enables REPL mode:\n\n```\n$ qsh -f js node\n```\n\nYou can use scripts and snippets with generic mode tools by setting the `QSH_SCRIPTS_PATH` and `QSH_SNIPPETS_PATH` environment variables. See the sections below for details on how these work.\n\nYou can register the settings you use for generic tools, including certain environment variables, just as you would register a connection for a database. This makes it easier to invoke the tool in the same way in the future. See the [registering connections](https://github.com/muhmud/qsh/#registering-connections) section for more details, or just run the `qsh` and/or `qsh-reg` tools without any arguments.\n\nFor example, the following registers an invocation for using `qsh` with `zsh`:\n\n```\n$ QSH_EDITOR_COMMAND=\"\\u001B\\u0016\" \\\n  QSH_NEWLINE_ON_COMMAND=1 \\\n  VISUAL=~/.qsh/scripts/qsh \\\n    qsh-reg -gisf sh zsh zsh\n```\n\n* `-g` - Grab environment variables, which will be restored when the tool is started\n* `-i` - Invoke the tool as is, i.e. without `rlwrap`\n* `-s` - Go straight into editor mode\n* `-f sh` - Set the file extension for the default file opened up in the editor to `sh`\n* `zsh` - The name of the invocation to create\n* `zsh` - The actual invocation of zsh\n\nNow this invocation of qsh can be started like this:\n\n```\n$ qsh zsh\n```\n\n#### Prefix\n\nYou can set `qsh` to add a prefix to every command you want to execute, which can be sometimes be useful in generic mode, for example, when running `git` or `kubectl` commands. This way you don't need to repeat this command every time.\n\n### Executing Queries\n\n* `Alt-e` - Highlight a query to run and execute it\n* `Alt-g` - Execute a query without needing to highlight it\n* `Alt-G` - Execute multiple statements or function/procedure definitions without needing to highlight\n* `Alt-y` - Execute everything in the editor buffer\n\nFor `Alt-g`, `qsh` will look for a statement delimited on either side by a semi-colon. This makes it easier to execute a large SQL statement without needing to highlight it every time.\n\nAlternatively, using `Alt-G` does the same thing but changes the delimiter to be the string `---`, which must be the only thing on a line. You can change this to whatever you like, this is simply the default as defined in the key mapping.\n\nThe following provides an example:\n\n```sql\ncreate procedure test(a int)\nbegin\n  update test\n    set a = 1;                  /* \u003c- If the cursor is here, Alt-G will create procedure test only */\nend;\n\n---                             /* \u003c- This is the customizable delimiter defined in the key binding */\n\ncreate procedure test2(a int)\nbegin\n  update test\n    set a = 2;                  /* \u003c- If the cursor is here, Alt-G will create procedure test2 only */\nend;\n```\n\n### Scripts\n\n* `Alt-v` - Execute a script, which can be done with or without highlighting\n\nScripts are shortcuts for SQL statements that return a consistent data set across different database servers. For example, to get a list of tables in the current database, whether `mysql` or `postgresql`, execute the following script(s):\n\n![Scripts](images/qsh-scripts.gif)\n\nYou can also apply additional filtering \u0026 sorting to scripts (you must highlight the query for this to work):\n\n```\ntables\nwhere table_schema = 'public'\norder by table_rows desc\n```\n\nThere are quite a few scripts available. You can see what they are by executing the `scripts` script. You can also add you own custom scripts to `~/.qsh/clients/psql/scripts` or `~/.qsh/clients/mysql/scripts`, depending on the database platform you are targeting.\n\nFor reference, here is an example of the kinds of scripts available:\n\n```\n$ ls ~/.qsh/clients/psql/scripts\nall-columns     all-references  all-sessions  columns    procedures  scripts      tables\nall-databases   all-routines    all-tables    databases  references  select       triggers\nall-functions   all-schemas     all-triggers  describe   routines    select-some  views\nall-procedures  all-select      all-views     functions  schemas     sessions\n\n```\n\nYou can keep your own scripts in separate directories and have `qsh` include them in its search by adding them to the `QSH_SCRIPTS_PATH` environment variable. \n\n#### Named Scripts\n\n* `Alt-d` - Describe a particular table, which may or may not be highlighted\n* `Alt-r` - Select some of the data for a particular table\n\nNamed scripts take information from the editor as a payload, which is used to provide context. The scripts mentioned above are created by default, however, you can also add your own.\n\nYou can either highlight the name of the table to be used with these scripts, however, it's also OK for the cursor to simply be on the table name.\n\n### Snippets\n\n* `Alt-Space` - Execute a snippet, which may or may not be highlighted\n\nSnippets are similar to scripts, however, the results are injected into the editor instead of being displayed as query results. You can also add your own custom snippets to `~/.qsh/clients/psql/snippets` for `postgresql`, for example.\n\n![Snippets](images/qsh-snippets.gif)\n\nThe snippets currently available are:\n\n* General\n   + `columns(\u003ctable-name\u003e)` - Get a comma-separated list of column names for a particular table\n\n* Scripting\n   + `script-function(\u003cfunction-name\u003e)` - Script out a function\n   + `script-procedure(\u003cprocedure-name\u003e)` - Script out a procedure\n   + `script-table(\u003ctable-name\u003e)` - Script out a table\n   + `script-trigger(\u003ctrigger-name\u003e)` - Script out a trigger\n   + `script-view(\u003cview-name\u003e)` - Script out a view\n\n**Note: When scripting tables for `postgresql`, the invocation of `psql` must be passed to `pg_dump`. If the invocation involves typing in a password, you will be prompted to enter it. For this reason, it may be better to [register a connection](https://github.com/muhmud/qsh/#registering-connections).**\n\nYou can keep your own snippets in separate directories and have `qsh` include them in its search by adding them to the `QSH_SNIPPETS_PATH` environment variable.\n\n#### Named Snippets\n\n* `Alt-t` - Format a SQL statement, which must be highlighted\n\nSimilar to named scripts, these snippets take a payload from the editor. Currently, this feature can be used to format a SQL statement.\n\n### Registering Connections\n\nYou can register connections for database servers that you access frequently. This can also be used to store the password for the connection using the native mechanism of each SQL client. This is achieved using the `qsh-reg` tool, and connection data will be stored under `~/.qsh/connections`.\n\nFor example:\n\n```\n$ qsh-reg -p dev-server psql -hmy-dev-server -Uroot -ddevdb\n```\n\nThis will register a connection called `dev-server` using the provided `psql` invocation. The `-p` option means that a password is to be stored, which the script will prompt you for.\n\nOnce the connection is registered, you can connect like this:\n\n```\n$ qsh dev-server\n```\n\nExecute `qsh-reg` without any arguments to see all the available options.\n\n#### Organising Connections\n\nConnections can also be organised into directories to any level of depth:\n\n```\n$ qsh-reg -p production/prod-db psql -h ...\n$ qsh-reg -p test/accounting/test-db mysql -h ...\n```\n\nYou would connect just as before:\n\n```\n$ qsh production/prod-db\n```\n\n#### Using Other Database Tools\n\nYou can also execute other tools using the connection info, such as `pg_dump`, using the `-c` option:\n\n```\n$ qsh -c pg_dump dev-server --table=public.some_table -s\n```\n\n## Options\n\nThe following environment variables can be changed if required:\n\n* `QSH_EDITOR` - The editor you are going to be using, which defaults to `$VISUAL`\n* `QSH_PAGER` - The pager you will be using, which by default will try `pspg`, `less`, and `cat` in that order.\n* `QSH_SCRIPTS_PATH` - Additional directories, separated by `:`, to search for scripts in\n* `QSH_SNIPPETS_PATH` - Additional directories, separated by `:`, to search for snippets in\n* `QSH_STARTUP_MODE` - If set to `1`, will make the `-s` option the default, and always startup the editor automatically\n\n## Using SSH\n\nTo work with database servers over SSH, you should install `qsh` on your remote host and start `tmux` in your SSH session. You won't, however, be able to get `qsh` to work when the editor is running locally and the SQL client is on a remote server, i.e. running within an SSH connection.\n\nIf possible, it might be easier to simply provide host and port connection details to the SQL client on your workstation and run everything locally.\n\n## Updating\n\nYou can update your local copy like this:\n\n```\n$ git -C ~/.qsh pull --rebase\n```\n\nIf you're using the `micro` editor, you will also need to update the editor plugin:\n\n```\n$ cp -r ~/.qsh/editors/micro/* ~/.config/micro/plug/qsh/.\n```\n\n## Exit\n\nTo clean up any temporary files \u0026 go back to normal, simply exit the editor. If you exit accidentally, just trigger the editor again, and it should go back to how it was.\n\nYou can also explicitly cleanup temporary files created by `qsh` by executing:\n\n```\n$ qsh-cleanup\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuhmud%2Fqsh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmuhmud%2Fqsh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuhmud%2Fqsh/lists"}