PostgreSQL跨实例FDW导入模式:如何保留列注释?
解决PostgreSQL FDW导入外模式时保留列注释的问题
IMPORT FOREIGN SCHEMA命令本身不会同步源表的列注释,因为它仅负责创建外表的基础结构(列名、数据类型等),不会携带注释这类元数据。要保留列级注释,需要手动或通过脚本同步,以下是两种可行方法:
方法一:手动生成并执行注释语句
- 在源数据库实例中执行以下SQL,导出目标模式下的列注释语句:
SELECT 'COMMENT ON COLUMN nom_schema_distant.' || quote_ident(c.relname) || '.' || quote_ident(a.attname) || ' IS ' || quote_literal(d.description) || ';' AS comment_stmt FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_class c ON n.oid = c.relnamespace JOIN pg_catalog.pg_attribute a ON c.oid = a.attrelid LEFT JOIN pg_catalog.pg_description d ON a.attrelid = d.objoid AND a.attnum = d.objsubid WHERE n.nspname = 'nom_schema_local' -- 源模式名 AND c.relkind = 'r' -- 仅筛选普通表 AND a.attnum > 0 -- 排除系统内部列 AND d.description IS NOT NULL; -- 仅导出存在注释的列
- 将查询结果中的所有
COMMENT语句复制到目标数据库实例中执行,即可为外表的列添加注释。
方法二:脚本批量同步
如果需要频繁同步注释,可以用shell脚本自动化这个过程(需确保本地安装了psql客户端):
# 从源库导出注释语句,自动替换为目标模式名并保存到临时文件 psql -h 源库IP -U 源库用户名 -d 源库名 -t -c "SELECT 'COMMENT ON COLUMN nom_schema_distant.' || quote_ident(c.relname) || '.' || quote_ident(a.attname) || ' IS ' || quote_literal(d.description) || ';' FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_class c ON n.oid = c.relnamespace JOIN pg_catalog.pg_attribute a ON c.oid = a.attrelid LEFT JOIN pg_catalog.pg_description d ON a.attrelid = d.objoid AND a.attnum = d.objsubid WHERE n.nspname = 'nom_schema_local' AND c.relkind = 'r' AND a.attnum > 0 AND d.description IS NOT NULL;" > sync_comments.sql # 在目标库执行注释同步语句 psql -h 目标库IP -U 目标库用户名 -d 目标库名 -f sync_comments.sql # 清理临时文件 rm sync_comments.sql
注意事项
- 外表的注释不会随源表注释的更新自动同步,若源表注释有修改,需要重新执行上述方法同步。
- 执行脚本时需要确保源库和目标库的用户有足够权限:源库用户需要能查询系统表
pg_namespace、pg_class、pg_attribute、pg_description;目标库用户需要能执行COMMENT ON COLUMN命令。
内容的提问来源于stack exchange,提问作者yam0925
相关产品推荐
相关产品推荐

