usql: universal psql?

01.2023 / Category: , / Tags: | |

usql? But why?

usql is a universal command-line interface for many database. But why are we still using CLI (command line utilities) in the 21st century? And what is wrong with psql?

Despite the widespread availability and ease of use of GUI-based tools, many people still prefer to use command line utilities for a number of reasons. These reasons include the ability to automate repetitive tasks, the ability to quickly and easily perform tasks that would be more time-consuming or difficult using a GUI, and the ability to access and control the computer from a remote location.

One example of a popular command line utility is psql, the command-line application for PostgreSQL. This application allows users to interact with a PostgreSQL database by typing SQL commands, as well as various psql-specific commands that can be used to list databases, connect to a specific database, view table schemas, and more. The ability to quickly and easily execute SQL commands using psql can be particularly useful for database administrators, as well as developers who are working with PostgreSQL databases.

One potential downside of using psql as a command-line application is it can be more difficult to use for those who are not familiar with typing commands and navigating a text-based interface. Additionally, because psql does not have a graphical user interface, it can be more difficult to visualize and interact with the data, especially for large and complex datasets. Also you should not forget about the poor support provided by Windows, like lack of tab completion, issues with encoding, etc. For example, you can read about my fight with Sublime Text and psql under Windows.

Another potential con of psql is that it is only designed to work with PostgreSQL databases, so users who work with other types of databases need to use a different tool. This can be particularly frustrating for users who are accustomed to using psql and are familiar with its commands, but need to switch to a different tool in order to work with another kind of database.

Is usql really good?

I don't know yet, even though I've already committed to the project. I will open two terminals side by side. In one I'll be using psql and in another usql. And we will see how different and/or better the second one is. I'll skip the installation part and start the test immediately.


$ psql -U pasha -h timetable
psql (13.0)
WARNING: Console code page (65001) differs from Windows code page (1251)
8-bit characters might not work correctly. See psql reference
page 'Notes for Windows users' for details.
Type 'help' for help.

Remember I told you about encodings? 😉

$ usql -U pasha -h timetable
usql.exe: error: unknown short flag '-U', try --help

$ usql -u pasha -h timetable
usql.exe: error: unknown short flag '-u', try --help


$ usql postgresql://pasha@
error: pq: SSL is not enabled on the server

$ usql postgresql://pasha@
Connected with driver postgres (PostgreSQL 13.0)
Type 'help' for help.

pg:pasha@127/Test=> conninfo
Connected with driver postgres (dbname=Test host= sslmode=disable user=pasha)


If you are used to connection parameters in psql then you're in trouble. Because usql only supports the DSN connection string. Which is absolutely fine for me, frankly speaking.

The SSL thing is not that good. I never enable it on my test environment and I believe the application should not force you to use SSL during the connection. But lib/pq library does exactly that and since it's used in usql, we have this behavior.

And the command prompt is corrupted. It should show the full host name or IP address instead of "127".

List databases

pg:pasha@127/timetable=> l
List of databases
Catalog | Owner | Encoding | Collate | Ctype | Access privileges
Test | pasha | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
clustergw | pasha | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
contrib_regression | pasha | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
pgx_test | pasha | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | pasha | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
regression | pasha | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | pasha | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/pasha +
| | | | | pasha=CTc/pasha
template1 | pasha | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/pasha +
| | | | | pasha=CTc/pasha
test | pasha | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
timetable | scheduler | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
МояУкраїнськаБазочка | pasha | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
(11 rows)

Works like a charm. Good! Plus one point! 🙂

Connect to a specific database

pg:pasha@172/timetable=> c Test
error: stat Test: no such file or directory

pg:pasha@127/timetable=> c postgresql://pasha@
error: pq: SSL is not enabled on the server

(not connected)=> c postgresql://pasha@
Connected with driver postgres (PostgreSQL 13.0)


OK, you need to use full DSN to connect to another database in the same cluster. Or use special notation, specifying the driver name and parameters. That's the price for support of many data sources including files and non relative databases. You must be precise as much as possible with a connection string.

Note the (not connected) prompt. You will see that a lot whenever a connection to another data source failed. usql even has a special Z command to close the database connection and switch to this mode. By comparison, psql will fail in a disconnected state only in rare cases of broken connections.

List objects in the database

According to the manual, many d commands are available. See below for a full list.

Let's try some, especially ss, which suppose to show stats for a table or a query. Interesting to see what will it return.

pg:pasha@127/timetable=> d
List of relations
Schema | Name | Type
public | location | table
timetable | chain_chain_id_seq | sequence
timetable | task | table
(11 rows)

pg:pasha@127/timetable=> dt
List of relations
Schema | Name | Type
public | location | table
timetable | task | table
(9 rows)

pg:pasha@127/timetable=> x
Expanded display is on.

pg:pasha@127/timetable=> df
List of functions
-[ RECORD 1 ]-------------------------------------------------------------------------------------------------------- Schema | public
Name | difference
Result data type | integer
Argument data types | text, text
-[ RECORD 36 ]--------------------------------------------------------------------------------------------------------
Schema | timetable
Name | validate_json_schema
Result data type | boolean
Argument data types | schema jsonb, data jsonb, root_schema jsonb

pg:pasha@127/timetable=> ss timetable.log
Column stats
Schema | Table | Name | Average width | Nulls fraction | Distinct values | Dist. fraction
timetable | log | ts | 0 | 0 | 0 | 1.0000
timetable | log | pid | 0 | 0 | 0 | 1.0000
timetable | log | log_level | 0 | 0 | 0 | 1.0000
timetable | log | client_name | 0 | 0 | 0 | 1.0000
timetable | log | message | 0 | 0 | 0 | 1.0000
timetable | log | message_data | 0 | 0 | 0 | 1.0000
(6 rows)

Some of the bugs were fixed immediately during this blog post writing! Wow! 🎉

And you can't list roles available. In psql there is the du command for that.

OK, how quickly can I get the info which commands from psql are present in usql?

List of common commands in usql and psql

Let's have some fun! We are programmers, after all!

$ comm --total -12
<(usql -c '?' | grep -E -o '^s{2}\w+' | sort -u) <(psql --help=commands | grep -E -o '^s{2}\w+' | sort -u) C H T a c cd conninfo copy copyright crosstabview d da df di dm dn dp ds dt dv e echo f g gexec gset gx i ir l o p password prompt pset q qecho r set setenv t timing unset w warn watch x 8 54 47 total [/shell] The comm command is used to compare the contents of two files or output streams and find the lines that are common to both. The --total flag indicates that the command should also output a summary line showing the number of lines that are unique to each file or output stream. The -12 flag indicates that the command should suppress lines that are unique to the first or second file/output stream, thus it returns only lines that are common to both. Omit this option if you want to see a 3-column output and check which commands are available solely in either psql or usql.

The <(...) syntax is used to create a temporary named pipe that can be used as an input to another command. In this case, the usql -c "?" command is executed and its output is piped through grep to extract all commands (using the -E -o '^s{2}\w+' flags) and then sorted using the sort command. All duplicates are ignored using the -u flag. The same is done for the psql --help=commands command.

Bottom line, there are:

  • 8 unique commands to usql;
  • 54 unique commands to psql;
  • 47 common commands in usql and psql.

But let's wrap up! This is supposed to be a "quick-look-at-usql" post.


In conclusion, both the usql and psql command-line applications offer a powerful tool for managing and querying databases. While they share many similar features, usql has a few additional capabilities such as

  • the ability to query across multiple databases and data sources,
  • syntax highlighting (what I love the most about it),
  • and psql command compatibility (not complete, but nevertheless).

However, it should be noted that usql is still in active development and may have some limitations or bugs compared to the more established psql application. Overall, the choice between the two ultimately depends on the specific needs and preferences of the user.

0 0 votes
Article Rating
Notify of
Inline Feedbacks
View all comments
CYBERTEC Logo white
CYBERTEC PostgreSQL International GmbH
Römerstraße 19
2752 Wöllersdorf

+43 (0) 2622 93022-0

Get the newest PostgreSQL Info & Tools

    This site is protected by reCAPTCHA and the Google Privacy Policy & Terms of Service apply.

    CYBERTEC PostgreSQL International GmbH
    Would love your thoughts, please comment.x
    linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram