【问题标题】:Get table schema in Redshift在 Redshift 中获取表模式
【发布时间】:2014-06-16 06:07:59
【问题描述】:

您好,我正在尝试检索现有表的架构。我是 mysql 开发人员,正在尝试使用 amazon redshift。如何导出现有表的架构。在 mysql 中我们可以使用 show create table 命令。

SHOW CREATE TABLE tblName;

【问题讨论】:

    标签: amazon-redshift


    【解决方案1】:

    红移请尝试

    show table <**tablename**> ;
    

    【讨论】:

      【解决方案2】:

      以下查询将为您生成表的 DDL:

      SELECT ddl
      FROM admin.v_generate_tbl_ddl
      WHERE schemaname = '<schemaname>'
      AND tablename in (
      '<tablename>');
      

      【讨论】:

        【解决方案3】:

        获取特定表的列数据和架构:

        • select * from information_schema.columns where tablename='table_name>>'

        要获取表元数据的信息,请触发以下查询

        • select * from information_schema.tables where schema='schema_name>>'

        【讨论】:

          【解决方案4】:

          您可以使用 AWS Redshift 提供的管理视图 - https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_tbl_ddl.sql

          创建视图后,您可以通过运行获取架构创建脚本:

          select * from <db_schema>.v_generate_tbl_ddl where tablename = '<table_name>'
          

          【讨论】:

            【解决方案5】:

            一种简单的方法是使用 AWS 提供的实用程序。您需要做的就是在数据库中创建视图,然后查询该视图以获取任何表 ddl。使用此视图的好处是它会为您提供 sortkey 和 distkey 以及在原始 create table 命令中使用的。

            https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_tbl_ddl.sql

            创建视图后,获取任何表的 ddl。你需要这样查询 -

            select ddl from table where tablename='table_name' and schemaname='schemaname';
            

            注意:您的集群中可能不存在管理员架构。因此,您可以在公共架构中创建此视图。

            【讨论】:

              【解决方案6】:

              由于显示表不适用于 Redshift:

              show table <YOUR_TABLE>;
              ERROR: syntax error at or near "<YOUR_TABLE>"
              

              我们可以使用 pg_table_def 表来获取模式:

              select "column", type, encoding, distkey, sortkey, "notnull" 
              from pg_table_def
              where tablename = '<YOUR_TABLE>';
              

              注意:如果架构不在搜索路径上,请使用以下命令将其添加到搜索路径:

              set search_path to '$user', 'public', '<YOUR_SCHEMA>';
              

              【讨论】:

              • SHOW TABLE &lt;table_name&gt;; 现在可以在 Redshift 中使用。
              【解决方案7】:

              最近我写了一个python脚本来克隆redshift集群之间的表模式。如果您只想要表格的列和列类型,您可以通过以下方式完成:

              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
              ;
              

              但是如果你需要压缩类型和distkey/sortkeys,你需要查询另一个表:

              select * from pg_table_def where tablename = 'xxx' and schemaname='xxx';
              

              【讨论】:

                【解决方案8】:

                以下命令将起作用:

                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 ;
                

                【讨论】:

                  【解决方案9】:

                  我没有找到任何完整的解决方案。 并写了一个python脚本:

                  https://github.com/cxmcc/redshift_show_create_table

                  它将像 pg_dump 一样工作,加上处理基本的红移功能、SORTKEY/DISTKEY/DISTSTYLES 等。

                  【讨论】:

                    【解决方案10】:

                    此查询将以 create 语句的形式为您提供完整的架构定义,包括 Redshift 特定属性分布类型/键、排序键、主键和列编码,并提供设置所有者的 alter table 语句给现在的主人。它唯一不能告诉你的是外键。我正在研究后者,但 RS 中当前存在特权问题,阻止我们查询正确的表。此查询可能需要一些调整,但我没有时间或需要进一步处理它。

                    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'
                    

                    【讨论】:

                    【解决方案11】:

                    如果你想得到带有create语句、约束和触发器的表结构,你可以使用pg_dump工具

                    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.
                    

                    这将输出带有所有约束的创建语法。希望这会对你有所帮助。

                    【讨论】:

                    • 对于 Postgres 7.3+,看起来 -d 标志从 pg_dump 中消失了,并且数据库是一个常规的命令行参数。即:pg_dump -U user_name -s -t table_name db_name.
                    • pg_dump 不会包含任何关于 sortkeys、distkeys、diststyle 或列编码的信息
                    【解决方案12】:

                    在 Postgres 中,您将查询目录。

                    psql 使用简写到各种命令,您可以使用\? 获得其列表(寻求帮助)。因此,无论是:

                    \d yourtable
                    \d+ yourtable
                    

                    要在应用中使用,您需要了解所涉及的相关查询。通过运行psql -E(用于回显隐藏查询)而不是普通的psql,这相对简单。

                    如果您需要精确的创建表语句,请参阅@Anant 答案。

                    【讨论】:

                      【解决方案13】:

                      您需要以编程方式还是从 psql 提示符中检索它?

                      在 psql 中使用:\d+ 表名

                      以编程方式,您可以查询此处记录的 ANSI 标准 INFORMATION_SCHEMA 视图:

                      http://www.postgresql.org/docs/9.1/static/information-schema.html
                      

                      INFORMATION_SCHEMA.TABLES 和 INFORMATION_SCHEMA.COLUMNS 视图应该有你需要的。

                      【讨论】:

                        猜你喜欢
                        • 2020-01-29
                        • 1970-01-01
                        • 2016-01-10
                        • 2019-05-23
                        • 1970-01-01
                        • 2017-11-03
                        • 1970-01-01
                        • 1970-01-01
                        • 2014-04-28
                        相关资源
                        最近更新 更多