如何处理数据仓库(PostgreSQL)文档?

时间:2012-06-27 14:12:52

标签: postgresql documentation data-warehouse

我们在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;

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

2 个答案:

答案 0 :(得分: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

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

答案 1 :(得分: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%'
)