This question already has answers here:
PostgreSQL "DESCRIBE TABLE"
(24 answers)
Closed 6 years ago.
I had employed MySQL for a couple of former projects. But now have
decided to switch to PostgreSQL. Not that version 8 also works on that,
ahem other OS which I'm stuck with at work.
But alas, two of the most useful commands appear to be missing:
SHOW TABLES
DESCRIBE table
Inasmuch as my prototyping DB is on my NetBSD server at home while my
data waiting to be 'based is at work, such that I have to connect via
Perl/DBI and XML-RPC (not psql, alas). The IT dept here just says, "Use
MS-Access", so no help there.
While I'm in the initial stage I need an informative way to blunder
around and see what's what as I try different ways to build this thing.
For that I had always relied on the two above from MySQL.
I can't believe there is no way for PostgreSQL to tell me what the
current DB's table structure is via simple SQL queries executed remotely.
Surely there must be. But I can't seem to find out from the couple of
books I have. All I dug up was some ultra-lame hack to get column names
for an already known table name by doing a "WHERE 1 != 1" or some such
so that no actual rows could be returned. Not very informative, that.
Surely I've missed the point, somewhere.
So enlighten me, please. What, pray tell, are the PostgreSQL-ish SQL
queries one uses so as to explore a given DB's table structure? What is
the PostgreSQL translation for "SHOW TABLES" and "DESCRIBE table"?
SHOW TABLES and DESCRIBE TABLE are MySQL-specific admin commands, and nothing to do with standard SQL.
You want the:
\d
and
\d+ tablename
commands from psql.
These are implemented client-side. I find this odd myself, and would love to move them server-side as built-in SQL commands one day.
Other clients provide other ways to browse the structure - for example, PgAdmin-III.
If you want a portable way to get table structure in code, you should use the information_schema views, which are SQL-standard. See information_schema. They're available in MySQL, PostgreSQL, Ms-SQL, and most other DBs. The downside is that they're fiddlier to use, so they aren't convenient for quick access when you're just browsing a DB structure.
As per the Documentation
SELECT
table_schema || '.' || table_name as show_tables
FROM
information_schema.tables
WHERE
table_type = 'BASE TABLE'
AND
table_schema NOT IN ('pg_catalog', 'information_schema');
for more convenience make it as a function
create or replace function show_tables() returns SETOF text as $$
SELECT
table_schema || '.' || table_name as show_tables
FROM
information_schema.tables
WHERE
table_type = 'BASE TABLE'
AND
table_schema NOT IN ('pg_catalog', 'information_schema');
$$
language sql;
So we can get the tables using
select show_tables()
For the table description
select column_name, data_type, character_maximum_length
from INFORMATION_SCHEMA.COLUMNS where table_name ='table_name';
as a Function
create or replace function describe_table(tbl_name text) returns table(column_name
varchar, data_type varchar,character_maximum_length int) as $$
select column_name, data_type, character_maximum_length
from INFORMATION_SCHEMA.COLUMNS where table_name = $1;
$$
language 'sql';
select * from describe_table('a_table_name');
Related
Is it possible to easily see what tables exist in what schemas, at a glance?
So far I have had to connect to a database, view the schemas, then change the search path to one of the schemas and then list the tables. I had to do this for multiple schemas until I found the table I was looking for.
What if there is a scenario where you inherit a poorly documented database and you want to find a specific table in hundreds of schemas?
Ideally I imagine some output like so;
SCHEMA TABLE
--------------------
schema1 table1
schema2 table2
schema2 table1
--------------------
Or even the more standard <SCHEMA_NAME>.<TABLE_NAME>;
schema1.table1
schema2.table2
schema2.table1
The latter output would be even better since you could simply check the table using copy-paste;
my-database=# \d schema2.table1
Ideally I'm hoping I missed a built-in command to find this. I don't really want to create and memorize a lengthy SQL command to get this (somewhat basic) information.
You can make use of pg_tables
SELECT schemaname, tablename,
quote_ident(schemaname) || '.' || quote_ident(tablename)
FROM pg_tables
WHERE tablename = 'test';
question is pretty simple, but can't seem to find a concrete answer anywhere.
I need to update all tables inside my postgresql schema to include a timestamp column with default NOW(). I'm wondering how I can do this via a query instead of having to go to each individual table. There are several hundred tables in the schema and they all just need to have the one column added with the default value.
Any help would be greatly appreciated!
The easy way with psql, run a query to generate the commands, save and run the results
-- Turn off headers:
\t
-- Use SQL to build SQL:
SELECT 'ALTER TABLE public.' || table_name || ' add fecha timestamp not null default now();'
FROM information_schema.tables
WHERE table_type = 'BASE TABLE' AND table_schema='public';
-- If the output looks good, write it to a file and run it:
\g out.tmp
\i out.tmp
-- or if you don't want the temporal file, use gexec to run it:
\gexec
Below is a great function to check the real count of all tables in PostgreSQL database. I found it here.
From my local test, it seems that the function returns the all result only after it finished all counting for 100 tables.
I am trying to make it more practical. If we could save the result of each table counting as soon as it finished with the table, then we can check the progress of all counting jobs instead of waiting for the end.
I think if I could UPDATE the result in this function immediately after finishing the first table, it will be great for my requirement.
Can you let me know how I can update the result into the table after this function finishes the counting of the first table?
CREATE FUNCTION rowcount_all(schema_name text default 'public')
RETURNS table(table_name text, cnt bigint) as
$$
declare
table_name text;
begin
for table_name in SELECT c.relname FROM pg_class c
JOIN pg_namespace s ON (c.relnamespace=s.oid)
WHERE c.relkind = 'r' AND s.nspname=schema_name
ORDER BY c.relname
LOOP
RETURN QUERY EXECUTE format('select count(*) from %I.%I',
table_name, schema_name, table_name);
END LOOP;
end
$$ language plpgsql;
-- Query
WITH rc(schema_name,tbl) AS (
select s.n,rowcount_all(s.n) from (values ('schema1'),('schema2')) as s(n)
)
SELECT schema_name,(tbl).* FROM rc;
Updated
I have decided to use a shell script to run the function below as a background process. The function would generate a processing log file so that I can check the current process.
I think your idea is good, but I also don't think it will work "out of the box" on PostgreSQL. I'm by no means the expert on this, but the way MVCC works on PostgreSQL, it's basically doing all of the DML in what can best be understood as temporary space, and then if and when everything works as expected it moves it all in at the end.
This has a lot of advantages, most notably that when someone is updating tables it doesn't prevent others from querying from those same tables.
If this were Oracle, I think you could accomplish this within the stored proc by using commit, but this isn't Oracle. And to be fair, Oracle doesn't allow truncates to be rolled back within a stored proc the way PostgreSQL does, so there are gives and takes.
Again, I'm not the expert, so if I've messed up a detail or two, feel free to correct me.
So, back to the solution. One way you COULD accomplish this is to set up your server as a remote server. Something like this would work:
CREATE SERVER pgprod
FOREIGN DATA WRAPPER dblink_fdw
OPTIONS (dbname 'postgres', host 'localhost', port '5432');
Assuming you have a table that stores the tables and counts:
create table table_counts (
table_name text not null,
record_count bigint,
constraint table_counts_pk primary key (table_name)
);
Were it not for your desire to see these results as they occur, something like this would work, for a single schema. It's easy enough to make this all schemas, so this is for illustration:
CREATE or replace FUNCTION rowcount_all(schema_name text)
returns void as
$$
declare
rowcount integer;
tablename text;
begin
for tablename in SELECT c.relname FROM pg_class c
JOIN pg_namespace s ON (c.relnamespace=s.oid)
WHERE c.relkind = 'r' AND s.nspname=schema_name
ORDER BY c.relname
LOOP
EXECUTE 'select count(*) from ' || schema_name || '.' || tablename into rowcount;
insert into table_counts values (schema_name || '.' || tablename, rowcount)
on conflict (table_name) do
update set record_count = rowcount;
END LOOP;
end
$$ language plpgsql;
(this presupposes 9.5 or greater -- if not, hand-roll your own upsert).
However, since you want real-time updates to the table, you could then put that same upsert into a dblink expression:
perform dblink_exec('pgprod', '
<< your upsert statement here >>
');
Of course the formatting of the SQL within the DBlink is now a little extra tricky, but the upside is once you nail it, you can run the function in the background and query the table while it's running to see the dynamic results.
I'd weigh that against the need to really have the information real-time.
How can a plain text list of the field names of table be retrieved from PostgreSQL database?
Just query INFORMATION_SCHEMA.COLUMNS, like this:
SELECT
column_name,
data_type,
character_maximum_length,
ordinal_position
FROM information_schema.columns
WHERE table_name = 'mytable'
Better still, INFORMATION_SCHEMA is almost universally supported by all popular SQL databases, so this should work anywhere.
If you really want just dump plain text file recipe, you can execute this query using command line psql and save it as CSV or something like that.
I have a problem where I need to remove all code and triggers from a database that relate to certain tables in order for a Solaris package to install. Long complicated story but I need
to start with a clean slate.
I've managed to remove all the existing tables/synonyms, but how to locate the code/triggers from sqlplus that is related?
Unfortunately, it's not feasible to drop the database and recreate it.
Well, it turns out all the table names are prefixed with my module name DAP.
So, to find all the table names and public synonyms with sqlplus:
select table_name from all_tables where table_name like 'DAP%';
select synonym_name from all_synonyms where table_name like 'DAP%';
To get a list of triggers and sequences
select trigger_name from all_triggers where table_name like 'DAP%';
select sequence_name from all_sequences where sequence_name like 'DAP%';
To get a list of all the constraints
select table_name, constraint_name from all_constraints where table_name like 'DAP%';
To get the DAP related code:
select text from dba_source where name like 'DAP%';
I can now write a script that drops everything.
You should be able to query the system table ALL_TRIGGERS to find the triggers. It has a table_name column. You can probably find the other related objects with different system tables (been awhile since I've messed with Oracle).
http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/statviews_2107.htm