代码之家  ›  专栏  ›  技术社区  ›  Adrian Serafin

Postgresql,获取表定义,pg_get_tabledef

  •  0
  • Adrian Serafin  · 技术社区  · 16 年前

    你知道postgresql 8.4中的pg_get_tabledef函数发生了什么吗?我肯定我在postgresql的早期版本中使用过它?

    1 回复  |  直到 7 年前
        1
  •  3
  •   filiprem    5 年前

    虽然 pg_get_tabledef 功能不是( 然而;-) )在PostgreSQL核心中,您可以使用这个可怜人的版本。适用于我,版本12和13适用于大多数典型用例:

    CREATE OR REPLACE FUNCTION tabledef(oid) RETURNS text
    LANGUAGE sql STRICT AS $$
    /* snatched from https://github.com/filiprem/pg-tools */
    WITH attrdef AS (
        SELECT
            n.nspname,
            c.relname,
            pg_catalog.array_to_string(c.reloptions || array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ') as relopts,
            c.relpersistence,
            a.attnum,
            a.attname,
            pg_catalog.format_type(a.atttypid, a.atttypmod) as atttype,
            (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid, true) for 128) FROM pg_catalog.pg_attrdef d
                WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) as attdefault,
            a.attnotnull,
            (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t
                WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) as attcollation,
            a.attidentity,
            a.attgenerated
        FROM pg_catalog.pg_attribute a
        JOIN pg_catalog.pg_class c ON a.attrelid = c.oid
        JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid
        LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)
        WHERE a.attrelid = $1
            AND a.attnum > 0
            AND NOT a.attisdropped
        ORDER BY a.attnum
    ),
    coldef AS (
        SELECT
            attrdef.nspname,
            attrdef.relname,
            attrdef.relopts,
            attrdef.relpersistence,
            pg_catalog.format(
                '%I %s%s%s%s%s',
                attrdef.attname,
                attrdef.atttype,
                case when attrdef.attcollation is null then '' else pg_catalog.format(' COLLATE %I', attrdef.attcollation) end,
                case when attrdef.attnotnull then ' NOT NULL' else '' end,
                case when attrdef.attdefault is null then ''
                    else case when attrdef.attgenerated = 's' then pg_catalog.format(' GENERATED ALWAYS AS (%s) STORED', attrdef.attdefault)
                        when attrdef.attgenerated <> '' then ' GENERATED AS NOT_IMPLEMENTED'
                        else pg_catalog.format(' DEFAULT %s', attrdef.attdefault)
                    end
                end,
                case when attrdef.attidentity<>'' then pg_catalog.format(' GENERATED %s AS IDENTITY',
                        case attrdef.attidentity when 'd' then 'BY DEFAULT' when 'a' then 'ALWAYS' else 'NOT_IMPLEMENTED' end)
                    else '' end
            ) as col_create_sql
        FROM attrdef
        ORDER BY attrdef.attnum
    ),
    tabdef AS (
        SELECT
            coldef.nspname,
            coldef.relname,
            coldef.relopts,
            coldef.relpersistence,
            string_agg(coldef.col_create_sql, E',\n    ') as cols_create_sql
        FROM coldef
        GROUP BY
            coldef.nspname, coldef.relname, coldef.relopts, coldef.relpersistence
    )
    SELECT
        format(
            'CREATE%s TABLE %I.%I%s%s%s;',
            case tabdef.relpersistence when 't' then ' TEMP' when 'u' then ' UNLOGGED' else '' end,
            tabdef.nspname,
            tabdef.relname,
            coalesce(
                (SELECT format(E'\n    PARTITION OF %I.%I %s\n', pn.nspname, pc.relname,
                    pg_get_expr(c.relpartbound, c.oid))
                    FROM pg_class c JOIN pg_inherits i ON c.oid = i.inhrelid
                    JOIN pg_class pc ON pc.oid = i.inhparent
                    JOIN pg_namespace pn ON pn.oid = pc.relnamespace
                    WHERE c.oid = $1),
                format(E' (\n    %s\n)', tabdef.cols_create_sql)
            ),
            case when tabdef.relopts <> '' then format(' WITH (%s)', tabdef.relopts) else '' end,
            coalesce(E'\nPARTITION BY '||pg_get_partkeydef($1), '')
        ) as table_create_sql
    FROM tabdef
    $$;
    

    SELECT tabledef('my_table'::regclass);
    
        2
  •  0
  •   VolkerK    16 年前

    看一看 \dt 指挥 http://www.postgresql.org/docs/8.4/interactive/app-psql.html

    -E
    --隐藏的回声
    回显\d和其他反斜杠命令生成的实际查询。 您可以使用它来研究psql的内部操作。这相当于在psql中设置隐藏的变量ECHO_。

    编辑和顺便说一句:

    http://markmail.org/message/3obwktwfnxfwspxg?q=pg_get_tabledef+type:announcements :

    ==PostgreSQL每周新闻-2007年3月31日==

    Bruce Momjian承诺:

    -由于缺乏兴趣,删除TODO:“添加pg_get_acldef()、pg_get_typedefault()、pg_get_attrdef()、pg_get_tabledef()、pg_get_domaindef()、pg_get_functiondef()