1

我们在 PostgreSQL 数据库中确实有一个小型数据仓库,我必须记录所有表。

我想我可以为每一列和每一表添加评论并使用管道“|” 分隔符添加更多属性。然后我可以使用信息模式和数组函数来获取文档并使用任何报告软件来创建所需的输出。

select
    ordinal_position,
    column_name,
    data_type,
    character_maximum_length,
    numeric_precision,
    numeric_scale,
    is_nullable,
    column_default,
    (string_to_array(descr.description,'|'))[1] as cs_name,
    (string_to_array(descr.description,'|'))[2] as cs_description,
    (string_to_array(descr.description,'|'))[3] as en_name,
    (string_to_array(descr.description,'|'))[4] as en_description,
    (string_to_array(descr.description,'|'))[5] as other
from 
    information_schema.columns columns
    join pg_catalog.pg_class klass on (columns.table_name = klass.relname and klass.relkind = 'r')
    left join pg_catalog.pg_description descr on (descr.objoid = klass.oid and descr.objsubid = columns.ordinal_position)
where 
    columns.table_schema = 'data_warehouse'
order by 
    columns.ordinal_position;

这是一个好主意还是有更好的方法?

4

2 回答 2

3

除非您必须包含系统表的描述,否则我不会尝试将您的描述硬塞到 pg_catalog.pg_description 中。制作自己的桌子。这样您就可以将列保留为列,而不必使用笨重的字符串函数。

或者,考虑按照javadoc的行向您的主模式文件添加特殊格式的注释。然后编写一个工具来提取这些评论并创建一个文档。这样,评论与他们正在评论的内容保持接近,并且您根本不必弄乱数据库来生成报告。例如:

--* Used for authentication.
create table users
(
  --* standard Rails-friendly primary key.  Also an example of
  --* a long comment placed before the item, rather than on the 
  --* the same line.
  id serial primary key,
  name text not null,     --* Real name (hopefully)
  login text not null,    --* Name used for authentication
  ...
);

您的文档工具会读取文件,查找--*评论,找出评论与内容相关的内容,并生成某种报告,例如:

table users: Used for authentication
  id: standard Rails-friendly primary key.  Also an example of a
      long comment placed before the item, rather than on the same
      line.
  name: Real name
  login: Name used for authentication

您可能会注意到,通过适当的注释,主模式文件本身就是一个非常好的报告,也许不需要其他任何东西。

于 2012-06-27T14:30:18.117 回答
1

如果有人感兴趣,这里是我用于我的小型文档项目的初始加载的内容。文档位于两张表中,一张用于描述表,一张用于描述列和约束。我很感激任何反馈。

/* -- Initial Load - Tables */

drop table dw_description_table cascade;

create table dw_description_table  (
  table_description_key serial primary key,
  physical_full_name character varying,
  physical_schema_name character varying,
  physical_table_name  character varying,
  Table_Type  character varying,   -- Fact Dimension   ETL Transformation
  Logical_Name_CS character varying,
  Description_CS character varying,
  Logical_Name_EN character varying,
  Description_EN character varying,
  ToDo  character varying,
  Table_Load_Type character varying,   --Manually TruncateLoad  AddNewRows
  Known_Exclusions character varying,
  Table_Clover_Script character varying
);



insert into dw_description_table (physical_full_name, physical_schema_name, physical_table_name) (

select 
    table_schema || '.' || table_name as physical_full_name, 
    table_schema, 
    table_name 
from 
    information_schema.tables 
where 
    table_name like 'dw%' or table_name like 'etl%'
)


/* -- Initial Load - Columns */


CREATE TABLE dw_description_column (
  column_description_key serial,
  table_description_key bigint,
  physical_full_name text,
  physical_schema_name character varying,
  physical_table_name  character varying,
  physical_column_name  character varying,
  ordinal_position  character varying,
  column_default  character varying,
  is_nullable  character varying,
  data_type  character varying,
  logical_name_cs  character varying,
  description_cs  character varying,
  logical_name_en  character varying,
  description_en  character varying,
  derived_rule  character varying,
  todo  character varying,
  pk_name  character varying,
  fk_name  character varying,
  foreign_table_name  character varying,
  foreign_column_name  character varying,
  is_primary_key boolean,
  is_foreign_key boolean,
  CONSTRAINT dw_description_column_pkey PRIMARY KEY (column_description_key ),
  CONSTRAINT fk_dw_description_table_key FOREIGN KEY (table_description_key)
      REFERENCES dw_description_table (table_description_key) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION  
);




insert into dw_description_column  ( 
    table_description_key ,  
    physical_full_name ,  
    physical_schema_name ,  
    physical_table_name  ,  
    physical_column_name ,  
    ordinal_position  ,  
    column_default  ,
    is_nullable  ,
    data_type  ,  
    logical_name_cs  ,  
    description_cs  ,  
    logical_name_en  ,  
    description_en  ,  
    derived_rule  ,  
    todo  ,  
    pk_name  ,
    fk_name  ,
    foreign_table_name  ,  
    foreign_column_name  ,  
    is_primary_key ,  
    is_foreign_key ) 

(

with

dw_constraints as (
SELECT  
    tc.constraint_name, 
    tc.constraint_schema || '.' || tc.table_name || '.' || kcu.column_name as physical_full_name,  
    tc.constraint_schema,
    tc.table_name, 
    kcu.column_name, 
    ccu.table_name AS foreign_table_name, 
    ccu.column_name AS foreign_column_name,
    TC.constraint_type
FROM 
    information_schema.table_constraints AS tc  
    JOIN information_schema.key_column_usage AS kcu ON (tc.constraint_name = kcu.constraint_name and tc.table_name = kcu.table_name)
    JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name
WHERE 
    constraint_type in ('PRIMARY KEY','FOREIGN KEY')
    AND tc.constraint_schema = 'bizdata'
    and (tc.table_name like 'dw%' or tc.table_name like 'etl%')
group by
    tc.constraint_name, 
    tc.constraint_schema,
    tc.table_name, 
    kcu.column_name, 
    ccu.table_name ,
    ccu.column_name,
    TC.constraint_type

)

select 
    dwdt.table_description_key,
    col.table_schema || '.' || col.table_name || '.' || col.column_name as physical_full_name, 
    col.table_schema as physical_schema_name, 
    col.table_name as physical_table_name, 
    col.column_name as physical_column_name, 
    col.ordinal_position, 
    col.column_default, 
    col.is_nullable, 
    col.data_type,
    null as Logical_Name_CS ,
    null as Description_CS ,
    null as Logical_Name_EN,
    null as Description_EN ,
    null as Derived_Rule ,
    null as ToDo,
    dwc1.constraint_name pk_name,
    dwc2.constraint_name as fk_name,
    dwc2.foreign_table_name,
    dwc2.foreign_column_name,
    case when dwc1.constraint_name is not null then true else false end as is_primary_key,
    case when dwc2.constraint_name is not null then true else false end as foreign_key
from 
    information_schema.columns col
    join dw_description_table dwdt on (col.table_schema || '.' || col.table_name = dwdt.physical_full_name )
    left join dw_constraints dwc1 on ((col.table_schema || '.' || col.table_name || '.' || col.column_name) = dwc1.physical_full_name and dwc1.constraint_type = 'PRIMARY KEY')
    left join dw_constraints dwc2 on ((col.table_schema || '.' || col.table_name || '.' || col.column_name) = dwc2.physical_full_name and dwc2.constraint_type = 'FOREIGN KEY') 
where 
    col.table_name like 'dw%' or col.table_name like 'etl%'
)
于 2012-06-29T12:23:48.043 回答