In this article, I will answer the questions: why isn’t there a SHOW TABLES command in PostgreSQL, when will SHOW TABLES in PostgreSQL be available, and how do I list tables with native PostgreSQL methods?
Why isn’t there a SHOW TABLES command in PostgreSQL?
People who come from MySQL are always asking the same question: why doesn’t the command SHOW TABLES
work in PostgreSQL ?
postgres=> SHOW TABLES; ERROR: unrecognized configuration parameter "tables"
First of all, there is a SHOW command in PostgreSQL, but it’s responsible for returning the value of a run-time parameter.
Now you know what the error message “unrecognized configuraton parameter” means: there is no run-time parameter with the name “tables”.
By the way, we have a comprehensive article on how to set PostgreSQL parameters.
But how can it be that the same command means opposite things in the two most popular open-source RDBMS? The answer is quite obvious: the SHOW
command is not part of the SQL ISO or ANSI standard. That allows anybody to use it as an extension to standard SQL.
When will SHOW TABLES be available in PostgreSQL?
I would say never! First, the SHOW
command has its own semantics in PostgreSQL. Second, it’s not part of the SQL standard. And probably it never will be, because the standard committee decided to use a different approach, called the Information Schema. However, even now, information schema support is not at the appropriate level in most databases.
How do I show tables in PostgreSQL?
Answers to this question may be found in a lot of places. I will just repeat them here.
The PostgreSQL way
If you’re using the psql
command-line utility, then try the \dt
built-in command.
Mnemonic rule: \dt = Describe Table
.
-- list visible tables from search_path timetable=> \dt List of relations Schema | Name | Type | Owner --------+-----------------+-------+----------- public | bar | table | scheduler public | foo | table | scheduler public | history_session | table | scheduler public | location | table | scheduler public | migrations | table | scheduler public | test | table | pasha (6 rows) -- list tables from "timetable" schema timetable=> \dt timetable.* List of relations Schema | Name | Type | Owner -----------+----------------+-------+----------- timetable | active_session | table | scheduler timetable | chain | table | scheduler timetable | chain_log | table | scheduler timetable | dummy_log | table | scheduler timetable | execution_log | table | scheduler timetable | log | table | scheduler timetable | migration | table | scheduler timetable | parameter | table | scheduler timetable | run_status | table | scheduler timetable | task | table | scheduler (10 rows) -- describe table "bar" timetable=> \dt bar List of relations Schema | Name | Type | Owner --------+------+-------+----------- public | bar | table | scheduler (1 row) -- describe table "bar" with details timetable=> \dt+ bar List of relations Schema | Name | Type | Owner | Persistence | Size | Description --------+------+-------+-----------+-------------+---------+------------- public | bar | table | scheduler | permanent | 0 bytes | (1 row)
If you’re using any other utility than psql
, then these SQLs are probably the best to show tables in PostgreSQL:
timetable=> SELECT n.nspname AS schema, t.relname AS table_name, t.relkind AS type, t.relowner::regrole AS owner FROM pg_class AS t JOIN pg_namespace AS n ON t.relnamespace = n.oid /* only tables and partitioned tables */ WHERE t.relkind IN ('r', 'p') /* exclude system schemas */ AND n.nspname !~~ ALL ('{pg_catalog,pg_toast,information_schema,pg_temp%}'); schema | table_name | type | owner --------------+-------------------+------+----------- timetable | chain_log | r | scheduler timetable | dummy_log | r | scheduler ... public | test | r | pasha public | location | r | scheduler (75 rows) timetable=> SELECT * FROM pg_catalog.pg_tables; schemaname | tablename | tableowner | tablespace | hasindexes | hasrules | hastriggers | rowsecurity --------------------+-------------------------+------------+------------+------------+----------+-------------+------------- timetable | chain_log | scheduler | | t | f | f | f pg_catalog | pg_statistic | pasha | | t | f | f | f pg_catalog | pg_type | pasha | | t | f | f | f timetable | dummy_log | scheduler | | t | f | f | f ... (82 rows)
But as you can see, they will list all the tables in the database, so you probably will need filtering anyway.
The ANSI standard way
As I said, there is a SQL-standard way to show tables in PostgreSQL by querying information_schema
:
timetable=> SELECT * FROM information_schema.tables WHERE table_type = 'BASE TABLE'; table_catalog | table_schema | table_name | table_type | self_referencing_column_name | reference_generation | user_defined_type_catalog | user_defined_type_schema | user_defined_type_name | is_insertable_into | is_typed | commit_action ---------------+--------------+------------------+------------+------------------------------+----------------------+---------------------------+--------------------------+------------------------+--------------------+----------+--------------- timetable | timetable | chain_log | BASE TABLE | | | | | | YES | NO | timetable | pg_catalog | pg_type | BASE TABLE | | | | | | YES | NO | timetable | timetable | dummy_log | BASE TABLE | | | | | | YES | NO | timetable | pg_catalog | pg_foreign_table | BASE TABLE | | | | | | YES | NO | timetable | timetable | migration | BASE TABLE | | | | | | YES | NO | ... (75 rows)
Conclusion
There is no universal way of doing common things in all databases. Even though the SQL standard declares the Information Schema to be the proper way, not every database manufacturer implemented its support on a decent level. If you’re using the native command-line psql
tool, you will have built-in commands; otherwise, you need to query system tables and/or views. If you’re using a GUI application, then you probably don’t have this problem. Every known GUI application with PostgreSQL support allows you to list, filter, and find any objects.
In case you were wondering how to compare the content of two PostgreSQL tables, see Hans’ post about creating checksums for tables.