列出 Amazon Redshift 中带有索引的列

List columns with indexes in Amazon Redshift

我需要查询 Redshift 元数据以获取 table 列的列表,其中包含该列是否是主键的一部分的信息。

post 已经 List columns with indexes in PostgreSQL 有一个针对 PostgreSQL 的答案,但是不幸的是,它在 Redshift 上失败 "ERROR: 42809: op ANY/ALL (array) requires array on right side"

使用以下查询:

select * from pg_table_def where tablename = 'mytablename'

这将为您提供 table 的所有列及其数据类型、编码以及它是否具有排序键或分布键。

借助这个https://bitbucket.org/zzzeek/sqlalchemy/pull-request/6/sqlalchemy-to-support-postgresql-80/diff

我想出了怎么做
SELECT attname column_name, attnotnull, 
  format_type(atttypid, atttypmod) as column_type, atttypmod,
  i.indisprimary as primary_key,
  col_description(attrelid, attnum) as description
FROM pg_attribute c
  LEFT OUTER JOIN pg_index i
  ON c.attrelid = i.indrelid AND i.indisprimary AND
  c.attnum = ANY(string_to_array(textin(int2vectorout(i.indkey)), ' '))
where c.attnum > 0 AND NOT c.attisdropped AND c.attrelid = :tableOid
order by attnum

您可以利用 AWS 几个月前 (https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_tbl_ddl.sql) 发布的 table DDL 视图,方法是选择约束组件并解析关键列:

select schemaname,tablename, substring(ddl,charindex('(',ddl)+1, charindex(')',ddl)-1-charindex('(',ddl)) 
from 
(
SELECT 
    n.nspname AS schemaname
   ,c.relname AS tablename
   ,200000000 + CAST(con.oid AS INT) AS seq
   ,'\t,' + pg_get_constraintdef(con.oid) AS ddl
  FROM
  pg_constraint AS con
  INNER JOIN pg_class AS c
    ON c.relnamespace = con.connamespace
    AND c.relfilenode = con.conrelid
  INNER JOIN pg_namespace AS n
    ON n.oid = c.relnamespace 
  WHERE c.relkind = 'r'
  ORDER BY seq
)

请注意,此查询还为您提供了外键列。通过在查询中附加

很容易过滤掉那些
   where ddl like '%PRIMARY KEY%'

以下对我有用:

    SELECT   n.nspname as schema_name,
       t.relname as table_name,
       i.relname as index_name,
       c.contype as index_type,
       a.attname as column_name,
       a.attnum AS column_position
    FROM  pg_class t
    INNER JOIN  pg_index      AS ix ON t.oid = ix.indrelid
    INNER JOIN  pg_constraint AS c  ON ix.indrelid = c.conrelid
    INNER JOIN  pg_class      AS i  ON i.oid = ix.indexrelid
    INNER JOIN  pg_attribute  AS a  ON a.attrelid = t.oid
    AND a.attnum= ANY(string_to_array(textin(int2vectorout(ix.indkey)),' ')::int[])
  INNER JOIN  pg_namespace  AS n  ON n.oid = t.relnamespace;