博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PostgreSQL 如何比较两个表的定义是否一致
阅读量:6419 次
发布时间:2019-06-23

本文共 6385 字,大约阅读时间需要 21 分钟。

一位网友提到的需求, 在PostgreSQL中如何比对两个表的定义差异.如果只比对字段类型, 不比对约束, 触发器, 策略, 权限等其他属性的话, 只需要使用pg_attribute这个catalog即可.例子 : 创建两个测试表, postgres=# create table tbl1 (id int, info text, c1 numeric(10,3), c2 timestamp without time zone);CREATE TABLEpostgres=# create table tbl2 (id int, info text, c0 int, c00 int, c1 numeric(10,3), c2 timestamp with time zone);CREATE TABLEpostgres=# alter table tbl2 drop column c00;ALTER TABLEpostgres=# alter table tbl2 add column c00 int;ALTER TABLEpostgres=# alter table tbl2 add column c01 int;ALTER TABLE当前结构postgres=# \d tbl1               Table "public.tbl1" Column |            Type             | Modifiers --------+-----------------------------+----------- id     | integer                     |  info   | text                        |  c1     | numeric(10,3)               |  c2     | timestamp without time zone | postgres=# \d tbl2              Table "public.tbl2" Column |           Type           | Modifiers --------+--------------------------+----------- id     | integer                  |  info   | text                     |  c0     | integer                  |  c1     | numeric(10,3)            |  c2     | timestamp with time zone |  c00    | integer                  |  c01    | integer                  | 使用这个catalogpostgres=# \d pg_attribute    Table "pg_catalog.pg_attribute"    Column     |   Type    | Modifiers ---------------+-----------+----------- attrelid      | oid       | not null attname       | name      | not null atttypid      | oid       | not null attstattarget | integer   | not null attlen        | smallint  | not null attnum        | smallint  | not null attndims      | integer   | not null attcacheoff   | integer   | not null atttypmod     | integer   | not null attbyval      | boolean   | not null attstorage    | "char"    | not null attalign      | "char"    | not null attnotnull    | boolean   | not null atthasdef     | boolean   | not null attisdropped  | boolean   | not null attislocal    | boolean   | not null attinhcount   | integer   | not null attcollation  | oid       | not null attacl        | aclitem[] |  attoptions    | text[]    |  attfdwoptions | text[]    | Indexes:    "pg_attribute_relid_attnam_index" UNIQUE, btree (attrelid, attname)    "pg_attribute_relid_attnum_index" UNIQUE, btree (attrelid, attnum)当前两个表在pg_attribute中的数据如下, 系统隐含列和已删除的列排除掉postgres=# select attrelid,attname,atttypid,attlen,atttypmod from pg_attribute where attrelid='tbl2'::regclass and attnum>=1 and not attisdropped; attrelid | attname | atttypid | attlen | atttypmod ----------+---------+----------+--------+-----------    24681 | id      |       23 |      4 |        -1    24681 | info    |       25 |     -1 |        -1    24681 | c0      |       23 |      4 |        -1    24681 | c1      |     1700 |     -1 |    655367    24681 | c2      |     1184 |      8 |        -1    24681 | c00     |       23 |      4 |        -1    24681 | c01     |       23 |      4 |        -1(7 rows)postgres=# select attrelid,attname,atttypid,attlen,atttypmod from pg_attribute where attrelid='tbl1'::regclass and attnum>=1 and not attisdropped; attrelid | attname | atttypid | attlen | atttypmod ----------+---------+----------+--------+-----------    24675 | id      |       23 |      4 |        -1    24675 | info    |       25 |     -1 |        -1    24675 | c1      |     1700 |     -1 |    655367    24675 | c2      |     1114 |      8 |        -1(4 rows)使用这个SQL就可以比对两个表不同的字段with t1 as (select attrelid,attname,attlen,format_type(atttypid,atttypmod) as typ from pg_attribute where attrelid='tbl1'::regclass and attnum>=1 and not attisdropped),t2 as (select attrelid,attname,attlen,format_type(atttypid,atttypmod) as typ from pg_attribute where attrelid='tbl2'::regclass and attnum>=1 and not attisdropped)select t1.*,t2.* from t1 full outer join t2 on (t1.attname = t2.attname and t1.typ=t2.typ and t1.attlen=t2.attlen) where t1.* is null or t2.* is null; attrelid | attname | atttypid | attlen | atttypmod | attrelid | attname | atttypid | attlen | atttypmod ----------+---------+----------+--------+-----------+----------+---------+----------+--------+-----------    24675 | c2      |     1114 |      8 |        -1 |          |         |          |        |                    |         |          |        |           |    24681 | c01     |       23 |      4 |        -1          |         |          |        |           |    24681 | c00     |       23 |      4 |        -1          |         |          |        |           |    24681 | c0      |       23 |      4 |        -1          |         |          |        |           |    24681 | c2      |     1184 |      8 |        -1(5 rows)长度不同也可以比对出来postgres=# alter table tbl1 add column n1 numeric(10,2);ALTER TABLEpostgres=# alter table tbl2 add column n1 numeric(10,3);ALTER TABLE使用format_type格式化一下类型, 更友好的输出postgres=# with                                         t1 as (select attrelid,attname,attlen,format_type(atttypid,atttypmod) as typ from pg_attribute where attrelid='tbl1'::regclass and attnum>=1 and not attisdropped),t2 as (select attrelid,attname,attlen,format_type(atttypid,atttypmod) as typ from pg_attribute where attrelid='tbl2'::regclass and attnum>=1 and not attisdropped)select t1.*,t2.* from t1 full outer join t2 on (t1.attname = t2.attname and t1.typ=t2.typ and t1.attlen=t2.attlen) where t1.* is null or t2.* is null; attrelid | attname | attlen |             typ             | attrelid | attname | attlen |           typ            ----------+---------+--------+-----------------------------+----------+---------+--------+--------------------------    24675 | c2      |      8 | timestamp without time zone |          |         |        |     24675 | n1      |     -1 | numeric(10,2)               |          |         |        |           |         |        |                             |    24681 | c0      |      4 | integer          |         |        |                             |    24681 | n1      |     -1 | numeric(10,3)          |         |        |                             |    24681 | c00     |      4 | integer          |         |        |                             |    24681 | c01     |      4 | integer          |         |        |                             |    24681 | c2      |      8 | timestamp with time zone(7 rows)如果你还需要比对其他的不同之处, 例如约束, 字段顺序, 触发器等, 建议用pg_dump将两个表的定义导出, 然后diff一下.或者研究一下pg_dump源码, 看看能不能找到更好的方法.

转载地址:http://qxmra.baihongyu.com/

你可能感兴趣的文章
一些软件设计软则
查看>>
Linux运维基础命令
查看>>
使用PowerShell配置IP地址
查看>>
第十一章 MySQL运算符
查看>>
JAVA常见算法题(十七)
查看>>
GUI鼠标相关设置
查看>>
使用 <Iframe>实现跨域通信
查看>>
闭包--循序学习
查看>>
项目实战之集成邮件开发
查看>>
解决C3P0在Linux下Failed to get local InetAddress for VMID问题
查看>>
1531 山峰 【栈的应用】
查看>>
巧用美女照做微信吸粉,你会做吗?
查看>>
wcf学习总结《上》
查看>>
ERROR (ClientException)
查看>>
WYSIWYG 网页在线编辑器比较表
查看>>
vss团队开发工具使用(个人学习心得)
查看>>
Load Balance 产品横向比较
查看>>
Java代理程序实现web方式管理邮件组成员
查看>>
【编译打包】tengine 1.5.1 SRPM
查看>>
看图说话:手动清除病毒文件流程
查看>>