Related
I wanted to compare the two tables employees and employees_a and find the missing columns in the table comployees_a.
select a.Column_name,
From User_tab_columns a
LEFT JOIN User_tab_columns b
ON upper(a.table_name) = upper(b.table_name)||'_A'
AND a.column_name = b.column_name
Where upper(a.Table_name) = 'EMPLOYEES'
AND upper(b.table_name) = 'EMPLOYEES_A'
AND b.column_name is NULL
;
But this doesnt seems to be working. No rows are returned.
My employees table has the below columns
emp_name
emp_id
base_location
department
current_location
salary
manager
employees_a table has below columns
emp_name
emp_id
base_location
department
current_location
I want to find the rest two columns and add them into employees_a table.
I have more than 50 tables like this to compare them and find the missing column and add those columns into their respective "_a" table.
Missing columns? Why not using the MINUS set operator, seems to be way simpler, e.g.
select column_name from user_tables where table_name = 'EMP_1'
minus
select column_name from user_tables where table_name = 'EMP_2'
Thirstly, check if user_tab_columns table contains columns of your tables (in my case user_tab_columns is empty and I have to use all_tab_columns):
select a.Column_name
From User_tab_columns a
Where upper(a.Table_name) = 'EMPLOYEES'
Secondly, remove line AND upper(b.table_name) = 'EMPLOYEES_A', because upper(b.table_name) is null in case a column is not found. You have b.table_name in JOIN part of the SELECT already.
select a.Column_name
From User_tab_columns a
LEFT JOIN User_tab_columns b
ON upper(a.table_name) = upper(b.table_name)||'_A'
AND a.column_name = b.column_name
Where upper(a.Table_name) = 'EMPLOYEES'
AND b.column_name is NULL
You do not need any joins and can use:
select 'ALTER TABLE EMPLOYEES_A ADD "'
|| Column_name || '" '
|| CASE MAX(data_type)
WHEN 'NUMBER'
THEN 'NUMBER(' || MAX(data_precision) || ',' || MAX(data_scale) || ')'
WHEN 'VARCHAR2'
THEN 'VARCHAR2(' || MAX(data_length) || ')'
END
AS sql
From User_tab_columns
Where Table_name IN ('EMPLOYEES', 'EMPLOYEES_A')
GROUP BY COLUMN_NAME
HAVING COUNT(CASE table_name WHEN 'EMPLOYEES' THEN 1 END) = 1
AND COUNT(CASE table_name WHEN 'EMPLOYEES_A' THEN 1 END) = 0;
Or, for multiple tables:
select 'ALTER TABLE ' || MAX(table_name) || '_A ADD "'
|| Column_name || '" '
|| CASE MAX(data_type)
WHEN 'NUMBER'
THEN 'NUMBER(' || MAX(data_precision) || ',' || MAX(data_scale) || ')'
WHEN 'VARCHAR2'
THEN 'VARCHAR2(' || MAX(data_length) || ')'
END
AS sql
From User_tab_columns
Where Table_name IN ('EMPLOYEES', 'EMPLOYEES_A', 'SOMETHING', 'SOMETHING_A')
GROUP BY
CASE
WHEN table_name LIKE '%_A'
THEN SUBSTR(table_name, 1, LENGTH(table_name) - 2)
ELSE table_name
END,
COLUMN_NAME
HAVING COUNT(CASE WHEN table_name NOT LIKE '%_A' THEN 1 END) = 1
AND COUNT(CASE WHEN table_name LIKE '%_A' THEN 1 END) = 0;
fiddle
This is how we can check table existence in MSSQL:
IF OBJECT_ID(N'public."TABLE_NAME"', N'U') IS NOT NULL
select 1 as 'column'
else
select 0 as 'column';
which stores outcome in variable 'column'
How can I do same thing in PostgreSQL ? I want to return 1 or 0 for respective outcome.
Use a SELECT with an EXISTS operator checking e.g. information_schema.tables:
select exists (select *
from information_schema.tables
where table_name = 'table_name'
and table_schema = 'public') as table_exists;
If you can't (or won't) deal with proper boolean values, the simply cast the result to a number (but I have no idea why that should be better):
select exists (select *
from information_schema.tables
where table_name = 'table_name'
and table_schema = 'public')::int as "column";
Note that column is a reserved keyword and thus you need to quote it using double quotes.
Check for column in a table existence use view pg_tables
IF EXISTS ( SELECT attname
FROM pg_attribute
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'YOURTABLENAME')
AND attname = 'YOURCOLUMNNAME')
THEN
-- do something
END IF;
For my sql use INFORMATION_SCHEMA.COLUMNS
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tbl_name'
[AND table_schema = 'db_name']
[AND column_name LIKE 'wild']
Can we able to get the queries for identifying unique column and not null column in schema.
Please refer below queries in oracle.
SELECT Table_name, index_name, num_rows, distinct_keys FROM dba_indexes WHERE table_owner = 'ownername' and uniqueness = 'NONUNIQUE' AND num_rows > 0 AND 100* ( num_rows - ( num_rows - distinct_keys ) ) / num_rows > 99 ;
SELECT t.table_name, c.column_name, t.num_rows, t.null_values FROM dba_tab_columns c, tab_tables t WHERE t.owner = 'ownername' and t.table_name=c.table_name and t.owner = c.owner and c.nullable='Y' and c.num_nulls=0;
Can we get same kind of queries in postgres?
Thanks
friend I had never needed what you need before but I found this and I hope you can use the reference
Equivalent of "describe table" in PgAdmin3
psql -d "$db_name" -c '
SELECT
ordinal_position , table_name , column_name , data_type , is_nullable
FROM information_schema.columns
WHERE 1=1
AND table_name = '\''my_table'\''
;'
# or just the col names
psql -d "$my_db" -t -c \
"SELECT column_name FROM information_schema.columns
WHERE 1=1 AND table_name='my_table'"
PostgreSQL "DESCRIBE TABLE"
https://www.postgresql.org/docs/9.3/static/information-schema.html
Excuse me for not doing the query
Below the queries will give result:
Finding columns which have unique data but no unique key index on those columns.
SELECT DISTINCT a.schemaname, a.tablename, attname, indexdef
FROM pg_stats a, pg_indexes b
WHERE a.tablename = b.tablename
AND a.schemaname ILIKE 'pegadata'
AND n_distinct = -1
AND indexdef NOT ILIKE '%UNIQUE%';
Finding columns which are never null but no constraint.
SELECT DISTINCT table_schema, table_name, column_name
FROM information_schema.columns a, pg_stats b
WHERE a.table_name = b.tablename
AND a.TABLE_SCHEMA = 'pegadata'
AND a.IS_NULLABLE = 'YES'
AND b.null_frac = 0;
I am trying to write a query that would (given a list of roles, and list of databases), list effective permissions for object of type database, schema, and table (to start with)
I have been trying to use has_XXX_privilege() functions but the output feels awkward...
Given 3 roles, for example, (app_rwc, app_rw, app_r) and a single db test_db I'd like to get output like this
role, obj_type, obj_name, has_permissions, missing_premissions
app_rwc, DATABASE, test_db, CREATE+CONNECT+TEMPORARY", NULL
app_rw, DATABASE, test_db, CONNECT+TEMPORARY, CREATE
app_r, DATABASE, test_db, CONNECT+TEMPORARY, CREATE
app_rwc, SCHEMA, audit, CREATE+USAGE, NULL
app_rwc, SCHEMA, shared, CREATE+USAGE, NULL
app_rw, SCHEMA, audit, USAGE, CREATE
app_rw, SCHEMA, shared, USAGE, CREATE
app_r, SCHEMA, audit, USAGE, CREATE
app_r, SCHEMA, audit, USAGE, CREATE
app_rwc, TABLE, audit.trail, SELECT+INSERT+UPDATE+DELETE+REFERENCES+TRIGGERS, TRUNCATE
etc
etc
So far this is what I got and it kind of works except it is verbose...
If anyone has a better approach please advise - thanks.
WITH
databases AS (
SELECT * FROM (VALUES ('app_prod')) AS t(database_name)
),
roles AS (
SELECT * FROM (VALUES ('app_rwc'), ('app_rw'), ('app_r')) AS t(role_name)
),
db_permissions AS (
SELECT * FROM (VALUES ('CREATE'), ('CONNECT'), ('TEMPORARY')) AS t(permission_name)
),
schemas AS (
SELECT
schema_name
FROM
information_schema.schemata
WHERE
catalog_name IN (SELECT database_name FROM databases)
AND schema_owner IN (SELECT role_name FROM roles)
),
schema_permissions AS (
SELECT * FROM (VALUES ('CREATE'), ('USAGE')) AS t(permission_name)
),
tables AS (
SELECT table_schema, table_name
FROM information_schema.tables
WHERE
table_catalog IN (SELECT database_name FROM databases)
AND table_schema IN (SELECT schema_name FROM schemas)
AND table_type IN ('BASE TABLE') -- , 'VIEW'
),
table_permissions AS (
SELECT * FROM (VALUES ('SELECT'), ('INSERT'), ('UPDATE'), ('DELETE'), ('TRUNCATE'), ('REFERENCES'), ('TRIGGER')) AS t(permission_name)
)
-- ----------------------------------------------------------------------------
SELECT
'DATABASE' AS obj_type
, databases.database_name AS obj_name
, roles.role_name
, db_permissions.permission_name
, has_database_privilege(roles.role_name, databases.database_name, db_permissions.permission_name) AS has_permission
FROM
databases
CROSS JOIN roles
CROSS JOIN db_permissions
-- ----------------------------------------------------------------------------
UNION ALL
-- ----------------------------------------------------------------------------
SELECT
'SCHEMA' AS obj_type
, schemas.schema_name AS obj_name
, roles.role_name
, schema_permissions.permission_name
, has_schema_privilege(roles.role_name, schemas.schema_name, schema_permissions.permission_name) AS has_permission
FROM
schemas
CROSS JOIN roles
CROSS JOIN schema_permissions
-- ----------------------------------------------------------------------------
UNION ALL
-- ----------------------------------------------------------------------------
SELECT
'TABLE' AS obj_type
, tables.table_schema || '.' || tables.table_name AS obj_name
, roles.role_name
, table_permissions.permission_name
, has_table_privilege(roles.role_name, (tables.table_schema || '.' || tables.table_name),table_permissions.permission_name) AS has_permission
FROM
tables
CROSS JOIN roles
CROSS JOIN table_permissions
UPDATE #1 - Here is expanded query (does types, sequences, and functions) with aggregation (Thanks to #filiprem for the tip!) Still rather large, but it does what I want it to do.
WITH
databases AS (
SELECT unnest('{app_prod}'::text[]) AS dbname
),
roles AS (
SELECT unnest('{app_rwc,app_rw,app_r}'::text[]) AS rname
),
permissions AS (
SELECT 'DATABASE' AS ptype, unnest('{CREATE,CONNECT,TEMPORARY}'::text[]) AS pname
UNION ALL
SELECT 'SCHEMA' AS ptype, unnest('{CREATE,USAGE}'::text[]) AS pname
UNION ALL
SELECT 'TABLE' AS ptype, unnest('{SELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER}'::text[]) AS pname
UNION ALL
SELECT 'SEQUENCE' AS ptype, unnest('{USAGE,SELECT,UPDATE}'::text[]) AS pname
UNION ALL
SELECT 'TYPE' AS ptype, unnest('{USAGE}'::text[]) AS pname
UNION ALL
SELECT 'FUNCTION' AS ptype, unnest('{EXECUTE}'::text[]) AS pname
),
schemas AS (
SELECT schema_name AS sname
FROM information_schema.schemata
WHERE catalog_name IN (SELECT dbname FROM databases) -- show schemas that exist in specified DB
AND schema_owner IN (SELECT rname FROM roles) -- show schemas that are owned by specified roles
OR schema_name IN ('public') -- always include these
--OR schema_name IN ('public', 'information_schema', 'pg_catalog')
),
tables AS (
SELECT table_schema AS tschema, table_name AS tname
FROM information_schema.tables
WHERE table_catalog IN (SELECT dbname FROM databases)
AND table_schema IN (SELECT sname FROM schemas)
AND table_type IN ('BASE TABLE') -- , 'VIEW'
),
sequences AS (
SELECT schemaname AS seqschema, sequencename AS seqname
FROM pg_sequences
WHERE schemaname IN (SELECT sname FROM schemas)
),
types AS (
SELECT nspname AS typeschema, typname AS typename, CASE typtype WHEN 'c' THEN 'composite' WHEN 'd' THEN 'domain' WHEN 'e' THEN 'enum' WHEN 'r' THEN 'range' ELSE 'other' END AS typekind
FROM pg_type INNER JOIN pg_namespace ON pg_type.typnamespace = pg_namespace.oid
WHERE nspname IN (SELECT sname FROM schemas)
AND typtype NOT IN ('b','p') -- exclude base and pseudo types
AND typname NOT IN (SELECT seqname FROM sequences) -- exclude sequences
),
functions AS (
SELECT nspname AS fnschema, proname AS fnname, pg_proc.oid AS fnoid, pg_get_function_arguments(pg_proc.oid) AS fnargs
FROM pg_proc INNER JOIN pg_namespace ON pg_proc.pronamespace = pg_namespace.oid
WHERE nspname IN (SELECT sname FROM schemas)
),
final AS (
SELECT
permissions.ptype
, databases.dbname AS obj_name
, roles.rname
, permissions.pname
, has_database_privilege(roles.rname, databases.dbname, permissions.pname) AS has_permission
FROM
databases
CROSS JOIN roles
CROSS JOIN permissions
WHERE
permissions.ptype = 'DATABASE'
UNION ALL -- ----------------------------------------------------------------------------------------------------------
SELECT
permissions.ptype
, schemas.sname AS obj_name
, roles.rname
, permissions.pname
, has_schema_privilege(roles.rname, schemas.sname, permissions.pname) AS has_permission
FROM
schemas
CROSS JOIN roles
CROSS JOIN permissions
WHERE
permissions.ptype = 'SCHEMA'
UNION ALL -- ----------------------------------------------------------------------------------------------------------
SELECT
permissions.ptype
, tables.tschema || '.' || tables.tname AS obj_name
, roles.rname
, permissions.pname
, has_table_privilege(roles.rname, (tables.tschema || '.' || tables.tname), permissions.pname) AS has_permission
FROM
tables
CROSS JOIN roles
CROSS JOIN permissions
WHERE
permissions.ptype = 'TABLE'
UNION ALL -- ----------------------------------------------------------------------------------------------------------
SELECT
permissions.ptype
, sequences.seqschema || '.' || sequences.seqname AS obj_name
, roles.rname
, permissions.pname
, has_sequence_privilege(roles.rname, (sequences.seqschema || '.' || sequences.seqname), permissions.pname) AS has_permission
FROM
sequences
CROSS JOIN roles
CROSS JOIN permissions
WHERE
permissions.ptype = 'SEQUENCE'
UNION ALL -- ----------------------------------------------------------------------------------------------------------
SELECT
permissions.ptype || ' - ' || types.typekind
, types.typeschema || '.' || types.typename AS obj_name
, roles.rname
, permissions.pname
, has_type_privilege(roles.rname, (types.typeschema || '.' || types.typename), permissions.pname) AS has_permission
FROM
types
CROSS JOIN roles
CROSS JOIN permissions
WHERE
permissions.ptype = 'TYPE'
UNION ALL -- ----------------------------------------------------------------------------------------------------------
SELECT
permissions.ptype
, functions.fnschema || '.' || functions.fnname || '(' || fnargs || ')' AS obj_name
, roles.rname
, permissions.pname
, has_function_privilege(roles.rname, functions.fnoid, permissions.pname) AS has_permission
FROM
functions
CROSS JOIN roles
CROSS JOIN permissions
WHERE
permissions.ptype = 'FUNCTION'
)
-- ====================================================================================================================
SELECT
rname AS role_name
, ptype AS object_type
, obj_name AS object_name
, string_agg(DISTINCT CASE WHEN has_permission THEN pname END, ',') AS granted_permissions
, string_agg(DISTINCT CASE WHEN NOT has_permission THEN pname END, ',') AS missing_premissions
FROM
final
GROUP BY 1, 2, 3
ORDER BY 1, 2, 3
Your query is good, you just need to add some aggregation. This is a start:
select obj_type, obj_name, role_name,
array_agg(distinct case when has_permission then permission_name end),
array_agg(distinct case when not has_permission then permission_name end)
from ( /* your query */ ) AS q1
group by 1,2,3
order by 1,2,3
Hello I am trying to retrieve the schema of an existing table. I am mysql developer and am trying to work with amazon redshift. How can I export the schema of an existing table. In mysql we can use the show create table command.
SHOW CREATE TABLE tblName;
Recently I wrote a python script to clone table schemas between redshift clusters. If you only want the columns and column types of a table, you can do it via:
select column_name,
case
when data_type = 'integer' then 'integer'
when data_type = 'bigint' then 'bigint'
when data_type = 'smallint' then 'smallint'
when data_type = 'text' then 'text'
when data_type = 'date' then 'date'
when data_type = 'real' then 'real'
when data_type = 'boolean' then 'boolean'
when data_type = 'double precision' then 'float8'
when data_type = 'timestamp without time zone' then 'timestamp'
when data_type = 'character' then 'char('||character_maximum_length||')'
when data_type = 'character varying' then 'varchar('||character_maximum_length||')'
when data_type = 'numeric' then 'numeric('||numeric_precision||','||numeric_scale||')'
else 'unknown'
end as data_type,
is_nullable,
column_default
from information_schema.columns
where table_schema = 'xxx' and table_name = 'xxx' order by ordinal_position
;
But if you need the compression types and distkey/sortkeys, you need to query another table:
select * from pg_table_def where tablename = 'xxx' and schemaname='xxx';
This query will give you the complete schema definition including the Redshift specific attributes distribution type/key, sort key, primary key, and column encodings in the form of a create statement as well as providing an alter table statement that sets the owner to the current owner. The only thing it can't tell you are foreign keys. I'm working on the latter, but there's a current privilege issue in RS that prevents us from querying the right tables. This query could use some tuning, but I haven't had time or the need to work it further.
select pk.pkey, tm.schemaname||'.'||tm.tablename, 'create table '||tm.schemaname||'.'||tm.tablename
||' ('
||cp.coldef
-- primary key
||decode(pk.pkey,null,'',pk.pkey)
-- diststyle and dist key
||decode(d.distkey,null,') diststyle '||dist_style||' ',d.distkey)
--sort key
|| (select decode(skey,null,'',skey) from (select
' sortkey(' ||substr(array_to_string(
array( select ','||cast(column_name as varchar(100)) as str from
(select column_name from information_schema.columns col where col.table_schema= tm.schemaname and col.table_name=tm.tablename) c2
join
(-- gives sort cols
select attrelid as tableid, attname as colname, attsortkeyord as sort_col_order from pg_attribute pa where
pa.attnum > 0 AND NOT pa.attisdropped AND pa.attsortkeyord > 0
) st on tm.tableid=st.tableid and c2.column_name=st.colname order by sort_col_order
)
,'')
,2,10000) || ')' as skey
))
||';'
-- additional alter table queries here to set owner
|| 'alter table '||tm.schemaname||'.'||tm.tablename||' owner to "'||tm.owner||'";'
from
-- t master table list
(
SELECT substring(n.nspname,1,100) as schemaname, substring(c.relname,1,100) as tablename, c.oid as tableid ,use2.usename as owner, decode(c.reldiststyle,0,'EVEN',1,'KEY',8,'ALL') as dist_style
FROM pg_namespace n, pg_class c, pg_user use2
WHERE n.oid = c.relnamespace
AND nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
AND c.relname <> 'temp_staging_tables_1'
and c.relowner = use2.usesysid
) tm
-- cp creates the col params for the create string
join
(select
substr(str,(charindex('QQQ',str)+3),(charindex('ZZZ',str))-(charindex('QQQ',str)+3)) as tableid
,substr(replace(replace(str,'ZZZ',''),'QQQ'||substr(str,(charindex('QQQ',str)+3),(charindex('ZZZ',str))-(charindex('QQQ',str)+3)),''),2,10000) as coldef
from
( select array_to_string(array(
SELECT 'QQQ'||cast(t.tableid as varchar(10))||'ZZZ'|| ','||column_name||' '|| decode(udt_name,'bpchar','char',udt_name) || decode(character_maximum_length,null,'', '('||cast(character_maximum_length as varchar(9))||')' )
-- default
|| decode(substr(column_default,2,8),'identity','',null,'',' default '||column_default||' ')
-- nullable
|| decode(is_nullable,'YES',' NULL ','NO',' NOT NULL ')
-- identity
|| decode(substr(column_default,2,8),'identity',' identity('||substr(column_default,(charindex('''',column_default)+1), (length(column_default)-charindex('''',reverse(column_default))-charindex('''',column_default) ) ) ||') ', '')
-- encoding
|| decode(enc,'none','',' encode '||enc)
as str
from
-- ci all the col info
(
select cast(t.tableid as int), cast(table_schema as varchar(100)), cast(table_name as varchar(100)), cast(column_name as varchar(100)),
cast(ordinal_position as int), cast(column_default as varchar(100)), cast(is_nullable as varchar(20)) , cast(udt_name as varchar(50)) ,cast(character_maximum_length as int),
sort_col_order , decode(d.colname,null,0,1) dist_key , e.enc
from
(select * from information_schema.columns c where c.table_schema= t.schemaname and c.table_name=t.tablename) c
left join
(-- gives sort cols
select attrelid as tableid, attname as colname, attsortkeyord as sort_col_order from pg_attribute a where
a.attnum > 0 AND NOT a.attisdropped AND a.attsortkeyord > 0
) s on t.tableid=s.tableid and c.column_name=s.colname
left join
(-- gives encoding
select attrelid as tableid, attname as colname, format_encoding(a.attencodingtype::integer) AS enc from pg_attribute a where
a.attnum > 0 AND NOT a.attisdropped
) e on t.tableid=e.tableid and c.column_name=e.colname
left join
-- gives dist col
(select attrelid as tableid, attname as colname from pg_attribute a where
a.attnum > 0 AND NOT a.attisdropped AND a.attisdistkey = 't'
) d on t.tableid=d.tableid and c.column_name=d.colname
order by ordinal_position
) ci
-- for the working array funct
), '') as str
from
(-- need tableid
SELECT substring(n.nspname,1,100) as schemaname, substring(c.relname,1,100) as tablename, c.oid as tableid
FROM pg_namespace n, pg_class c
WHERE n.oid = c.relnamespace
AND nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
) t
)) cp on tm.tableid=cp.tableid
-- primary key query here
left join
(select c.oid as tableid, ', primary key '|| substring(pg_get_indexdef(indexrelid),charindex('(',pg_get_indexdef(indexrelid))-1 ,60) as pkey
from pg_index i , pg_namespace n, pg_class c
where i.indisprimary=true
and i.indrelid =c.oid
and n.oid = c.relnamespace
) pk on tm.tableid=pk.tableid
-- dist key
left join
( select
-- close off the col defs after the primary key
')' ||
' distkey('|| cast(column_name as varchar(100)) ||')' as distkey, t.tableid
from information_schema.columns c
join
(-- need tableid
SELECT substring(n.nspname,1,100) as schemaname, substring(c.relname,1,100) as tablename, c.oid as tableid
FROM pg_namespace n, pg_class c
WHERE n.oid = c.relnamespace
AND nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
) t on c.table_schema= t.schemaname and c.table_name=t.tablename
join
-- gives dist col
(select attrelid as tableid, attname as colname from pg_attribute a where
a.attnum > 0 AND NOT a.attisdropped AND a.attisdistkey = 't'
) d on t.tableid=d.tableid and c.column_name=d.colname
) d on tm.tableid=d.tableid
where tm.schemaname||'.'||tm.tablename='myschema.mytable'
If you want to get the table structure with create statement, constraints and triggers, you can use pg_dump utility
pg_dump -U user_name -s -t table_name -d db_name
Note: -s used for schema only dump
if you want to take the data only dump , you can use -a switch.
This will output the create syntax with all the constraints. Hope this will help you.
I did not find any complete solutions out there.
And wrote a python script:
https://github.com/cxmcc/redshift_show_create_table
It will work like pg_dump, plus dealing with basic redshift features, SORTKEY/DISTKEY/DISTSTYLES etc.
As show table doesn't work on Redshift:
show table <YOUR_TABLE>;
ERROR: syntax error at or near "<YOUR_TABLE>"
We can use pg_table_def table to get the schema out:
select "column", type, encoding, distkey, sortkey, "notnull"
from pg_table_def
where tablename = '<YOUR_TABLE>';
NOTE: If the schema is not on the search path, add it to search path using:
set search_path to '$user', 'public', '<YOUR_SCHEMA>';
For redshift please try
show table <**tablename**> ;
In Postgres, you'd query the catalog.
From with psql use the shorthands to a variety of commands whose list you'll get by using \? (for help). Therefor, either of:
\d yourtable
\d+ yourtable
For use in an app, you'll need to learn the relevant queries involved. It's relatively straightforward by running psql -E (for echo hidden queries) instead of plain psql.
If you need the precise create table statement, see #Anant answer.
One easy way to do this is to use the utility provided by AWS. All you need to do is to create the view in your database and then query that view to get any table ddl. The advantage to use this view is that it will give you the sortkey and distkey as well which was used in original create table command.
https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_tbl_ddl.sql
Once the view is created, to get the the ddl of any table. You need to query like this -
select ddl from table where tablename='table_name' and schemaname='schemaname';
Note: Admin schema might not be already there in your cluster. So you can create this view in public schema.
Below query will generate the DDL of the table for you:
SELECT ddl
FROM admin.v_generate_tbl_ddl
WHERE schemaname = '<schemaname>'
AND tablename in (
'<tablename>');
Are you needing to retrieve it programatically or from the psql prompt?
In psql use : \d+ tablename
Programatically, you can query the ANSI standard INFORMATION_SCHEMA views documented here:
http://www.postgresql.org/docs/9.1/static/information-schema.html
The INFORMATION_SCHEMA.TABLES and INFORMATION_SCHEMA.COLUMNS views should have what you need.
You can use admin view provided by AWS Redshift - https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_tbl_ddl.sql
once you have created the view you can get schema creation script by running:
select * from <db_schema>.v_generate_tbl_ddl where tablename = '<table_name>'
To get the column data and schema of a particular table:
select * from information_schema.columns where tablename='<<table_name>>'
To get the information of a table metadata fire the below query
select * from information_schema.tables where schema='<<schema_name>>'
In the new "query editor 2", you can right click on a table and select "show definition", this will place the DDL for the table in a query window.
The below command will work:
mysql > show create table test.users_info;
Redshift/postgress >pg_dump -U root-w --no-password -h 62.36.11.547 -p 5439 -s -t test.users_info ;