【PostgreSQL】PostgreSQL使用dblink来比对两个数据库之间的ddl差异

【PostgreSQL】PostgreSQL使用dblink来比对两个数据库之间的ddl差异


引言

我们经常会遇到两个环境的ddl要拉齐,比如开发环境(dev)和生产环境(pro),下面我们可以通过PostgreSQL的dblink插件来实现。

一、创建视图tab_info_tzq_dev

create view tab_info_tzq_dev as 
select * 
  from dblink('host=IP地址 dbname=数据库名 port=5432 user=用户名 password=密码',
'SELECT n.nspname AS schemaname
          ,c.relname AS tablename
          ,(col_description(c.oid, 0))::character varying AS table_comment
          ,a.attnum AS colnum
          ,a.attname AS columnname
          ,concat_ws('''', t.typname) AS columntype
          ,(CASE
             WHEN a.attlen > 0 THEN
               a.attlen
             WHEN t.typname = ''bit'' THEN
               a.atttypmod
             ELSE
               a.atttypmod - 4
           END) AS columntlength
          ,CASE
            WHEN (((format_type(a.atttypid, a.atttypmod))::character varying)::text = ''bigint''::text) THEN ''INT8''::character varying
            WHEN (((format_type(a.atttypid, a.atttypmod))::character varying)::text = ''smallint''::text) THEN ''INT2''::character varying
            WHEN (((format_type(a.atttypid, a.atttypmod))::character varying)::text = ''integer''::text) THEN ''INT4''::character varying
            WHEN ("left"(((format_type(a.atttypid, a.atttypmod))::character varying)::text, 17) = ''character varying''::text) THEN (replace(((format_type(a.atttypid, a.atttypmod))::character varying)::text, ''character varying''::text, ''VARCHAR''::text))::character varying
            WHEN ("left"(((format_type(a.atttypid, a.atttypmod))::character varying)::text, 9) = ''character''::text) THEN (replace(((format_type(a.atttypid, a.atttypmod))::character varying)::text, ''character''::text, ''char''::text))::character varying
            ELSE (format_type(a.atttypid, a.atttypmod))::character varying
        END AS typelen
          ,(CASE
             WHEN a.attnotnull = TRUE THEN
               ''NOT NULL''
             ELSE
               NULL
           END) AS is_null
          ,(CASE
             WHEN (SELECT COUNT(pg_constraint.*)
                     FROM pg_constraint
                    INNER JOIN pg_class
                       ON pg_constraint.conrelid = pg_class.oid
                    INNER JOIN pg_attribute
                       ON pg_attribute.attrelid = pg_class.oid
                      AND pg_attribute.attnum = ANY(pg_constraint.conkey)
                    INNER JOIN pg_type
                       ON pg_type.oid = pg_attribute.atttypid
                    WHERE pg_class.relname = c.relname
                      AND pg_constraint.contype = ''p''
                      AND pg_attribute.attname = a.attname) > 0 THEN
               ''Y''
             ELSE
               NULL
           END) AS pkey
          ,col.is_identity AS auto_increment
          ,col.column_default AS column_default
          ,(SELECT description
              FROM pg_description
             WHERE objoid = a.attrelid
               AND objsubid = a.attnum) AS column_comment
      FROM pg_class                   c
          ,pg_attribute               a
          ,pg_type                    t
          ,information_schema.columns AS col
          ,pg_namespace               n
     WHERE 1 = 1
       AND a.attnum > 0
       AND a.attrelid = c.oid
       AND a.atttypid = t.oid
       AND col.table_name = c.relname
       AND col.column_name = a.attname
       AND col.table_schema = CURRENT_SCHEMA
       AND n.oid = c.relnamespace
       AND n.nspname = CURRENT_SCHEMA
			 and c.relname not like ''act\_%''
       and (c.relname like ''%\_t'' OR c.relname like ''%\_ti'' OR c.relname like ''%\_tmp'')
     ORDER BY c.relname ASC
             ,a.attnum  ASC
')
as t(
  schemaname varchar(64),
	tablename varchar(64),
	table_comment varchar(4000),
	colnum int8,
	columnname varchar(64),
	columntype varchar(256),
	columntlength int8,
	typelen varchar(256),
	is_null varchar(256),
	pkey varchar(256),
	auto_increment varchar(256),
	column_default varchar(256),
	column_comment varchar(4000)
);

查询:

select * from tab_info_tzq_dev;

二、创建视图tab_info_tzq_pro

create view tab_info_tzq_pro as 
select * 
  from dblink('host=IP地址 dbname=数据库名 port=5432 user=用户名 password=密码',
'SELECT n.nspname AS schemaname
          ,c.relname AS tablename
          ,(col_description(c.oid, 0))::character varying AS table_comment
          ,a.attnum AS colnum
          ,a.attname AS columnname
          ,concat_ws('''', t.typname) AS columntype
          ,(CASE
             WHEN a.attlen > 0 THEN
               a.attlen
             WHEN t.typname = ''bit'' THEN
               a.atttypmod
             ELSE
               a.atttypmod - 4
           END) AS columntlength
          ,CASE
            WHEN (((format_type(a.atttypid, a.atttypmod))::character varying)::text = ''bigint''::text) THEN ''INT8''::character varying
            WHEN (((format_type(a.atttypid, a.atttypmod))::character varying)::text = ''smallint''::text) THEN ''INT2''::character varying
            WHEN (((format_type(a.atttypid, a.atttypmod))::character varying)::text = ''integer''::text) THEN ''INT4''::character varying
            WHEN ("left"(((format_type(a.atttypid, a.atttypmod))::character varying)::text, 17) = ''character varying''::text) THEN (replace(((format_type(a.atttypid, a.atttypmod))::character varying)::text, ''character varying''::text, ''VARCHAR''::text))::character varying
            WHEN ("left"(((format_type(a.atttypid, a.atttypmod))::character varying)::text, 9) = ''character''::text) THEN (replace(((format_type(a.atttypid, a.atttypmod))::character varying)::text, ''character''::text, ''char''::text))::character varying
            ELSE (format_type(a.atttypid, a.atttypmod))::character varying
        END AS typelen
          ,(CASE
             WHEN a.attnotnull = TRUE THEN
               ''NOT NULL''
             ELSE
               NULL
           END) AS is_null
          ,(CASE
             WHEN (SELECT COUNT(pg_constraint.*)
                     FROM pg_constraint
                    INNER JOIN pg_class
                       ON pg_constraint.conrelid = pg_class.oid
                    INNER JOIN pg_attribute
                       ON pg_attribute.attrelid = pg_class.oid
                      AND pg_attribute.attnum = ANY(pg_constraint.conkey)
                    INNER JOIN pg_type
                       ON pg_type.oid = pg_attribute.atttypid
                    WHERE pg_class.relname = c.relname
                      AND pg_constraint.contype = ''p''
                      AND pg_attribute.attname = a.attname) > 0 THEN
               ''Y''
             ELSE
               NULL
           END) AS pkey
          ,col.is_identity AS auto_increment
          ,col.column_default AS column_default
          ,(SELECT description
              FROM pg_description
             WHERE objoid = a.attrelid
               AND objsubid = a.attnum) AS column_comment
      FROM pg_class                   c
          ,pg_attribute               a
          ,pg_type                    t
          ,information_schema.columns AS col
          ,pg_namespace               n
     WHERE 1 = 1
       AND a.attnum > 0
       AND a.attrelid = c.oid
       AND a.atttypid = t.oid
       AND col.table_name = c.relname
       AND col.column_name = a.attname
       AND col.table_schema = CURRENT_SCHEMA
       AND n.oid = c.relnamespace
       AND n.nspname = CURRENT_SCHEMA
			 and c.relname not like ''act\_%''
       and (c.relname like ''%\_t'' OR c.relname like ''%\_ti'' OR c.relname like ''%\_tmp'')
     ORDER BY c.relname ASC
             ,a.attnum  ASC
')
as t(
  schemaname varchar(64),
	tablename varchar(64),
	table_comment varchar(4000),
	colnum int8,
	columnname varchar(64),
	columntype varchar(256),
	columntlength int8,
	typelen varchar(256),
	is_null varchar(256),
	pkey varchar(256),
	auto_increment varchar(256),
	column_default varchar(256),
	column_comment varchar(4000)
);

查询:

select * from tab_info_tzq_pro;

三、比较差异

select 'DEV' AS source,t.* from tab_info_tzq_dev t
EXCEPT
select 'DEV' AS source,t.* from tab_info_tzq_pro t
union all
select 'PRO' AS source,t.* from tab_info_tzq_pro t
EXCEPT
select 'PRO' AS source,t.* from tab_info_tzq_dev t
ORDER BY tablename, columnname;

四、差异处理

根据比较差异得出的结果,能查到结果说明就有问题。依次进行处理,处理完之后查不到差异结果了才对。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tzq@2018

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值