PostgreSQL 使用函数生成 外部表DDL

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS SQL Server,基础系列 2核4GB
简介:

如果要生成大量的外部表, 写代码闲麻烦的话, PostgreSQL 9.5 可以通过import foreign schema 一键创建外部表, 以前的版本则可以通过如下方法快速的生成外部表的DDL.
创建postgresql外部表fdw

postgres=# create extension postgres_fdw;  
CREATE EXTENSION  

创建server, 指定远端数据库的ip, port, dbname

postgres=# create server fs foreign data wrapper postgres_fdw options (hostaddr '172.16.3.150', port '1921', dbname 'postgres');  
CREATE SERVER  

创建一个本地角色

postgres=# create role test login encrypted password 'test';  
CREATE ROLE  

配置本地角色teset使用server的user mapping, 指定连接到server的用户,密码.

postgres=# CREATE USER MAPPING FOR test SERVER fs OPTIONS (user 'postgres', password 'postgres');  
CREATE USER MAPPING  

将server的使用权给本地用户test

postgres=# grant usage on FOREIGN SERVER  fs to test;  
GRANT  

假设远端有一个表是orig

postgres=# \d orig  
     Table "public.orig"  
 Column |  Type   | Modifiers  
--------+---------+-----------  
 id     | integer |   
 x      | numeric |   

在test 用户下创建外部表

postgres=# \c postgres test  
You are now connected to database "postgres" as user "test".  
postgres=> create foreign table f_orig (id int, x numeric) server fs options(schema_name 'public', table_name 'orig');  
CREATE FOREIGN TABLE  

配置远端数据库的 pg_hba.conf, 允许访问.

postgres@db-172-16-3-150-> cd $PGDATA  
postgres@db-172-16-3-150-> vi pg_hba.conf  
host all all 0.0.0.0/0 md5  
"pg_hba.conf" 94L, 4495C written  
postgres@db-172-16-3-150-> pg_ctl reload  
server signaled  

测试外部表的访问

postgres=# \c postgres test  
You are now connected to database "postgres" as user "test".  
postgres=> select * from f_orig;  
  id  |   x      
------+--------  
    1 |  93.23  
    2 |  95.24  
    3 |  95.19  
.............  

为了快速刷新物化视图, 原表最好有UK或PK

postgres=> \c postgres postgres  
You are now connected to database "postgres" as user "postgres".  
postgres=# \d orig  
     Table "public.orig"  
 Column |  Type   | Modifiers   
--------+---------+-----------  
 id     | integer |   
 x      | numeric |   

postgres=# create unique index uk_orig on orig(id);  
CREATE INDEX  

使用如下函数自动生成外部表的DDL, 需要指定本地表的schema, tbl_name, 以及外部表需要创建在哪个schema下, 外部表的名称.

create or replace function create_ft(i_schema name, i_tbl name, i_ftschema text, i_ftname text) returns text as $$  
declare  
  v_attname name;  
  v_type text;  
  v_sql text;  
  v_nt text := '';  
  v_oid oid;  
begin  
  select oid into v_oid from pg_class where relnamespace=(select oid from pg_namespace where nspname=i_schema) and relname=i_tbl;  
  v_sql := 'create foreign table '||i_ftschema||'.'||i_ftname||' (';  
  for v_attname,v_type in SELECT a.attname,  
    pg_catalog.format_type(a.atttypid, a.atttypmod)  
    FROM pg_catalog.pg_attribute a  
    WHERE a.attrelid = v_oid AND a.attnum > 0 AND NOT a.attisdropped  
    ORDER BY a.attnum   
  LOOP  
    v_nt := v_nt||v_attname||' '||v_type||','||chr(10);  
  END LOOP;  
  select regexp_replace(v_nt,','||chr(10)||'$','') into v_nt;  
  v_sql := v_sql||v_nt||$_$) server fs options(schema_name '$_$||i_schema||$_$', table_name '$_$||i_tbl||$_$');$_$;  
  return v_sql;  
end;  
$$ language plpgsql strict;  

如下 :

postgres=# select create_ft('pg_catalog','pg_class','public','f_orig');  
                                       create_ft                                          
----------------------------------------------------------------------------------------  
 create foreign table public.f_orig (relname name,                                     +  
 relnamespace oid,                                                                     +  
 reltype oid,                                                                          +  
 reloftype oid,                                                                        +  
 relowner oid,                                                                         +  
 relam oid,                                                                            +  
 relfilenode oid,                                                                      +  
 reltablespace oid,                                                                    +  
 relpages integer,                                                                     +  
 reltuples real,                                                                       +  
 relallvisible integer,                                                                +  
 reltoastrelid oid,                                                                    +  
 relhasindex boolean,                                                                  +  
 relisshared boolean,                                                                  +  
 relpersistence "char",                                                                +  
 relkind "char",                                                                       +  
 relnatts smallint,                                                                    +  
 relchecks smallint,                                                                   +  
 relhasoids boolean,                                                                   +  
 relhaspkey boolean,                                                                   +  
 relhasrules boolean,                                                                  +  
 relhastriggers boolean,                                                               +  
 relhassubclass boolean,                                                               +  
 relispopulated boolean,                                                               +  
 relreplident "char",                                                                  +  
 relfrozenxid xid,                                                                     +  
 relminmxid xid,                                                                       +  
 relacl aclitem[],                                                                     +  
 reloptions text[]) server fs options(schema_name 'pg_catalog', table_name 'pg_class');  
(1 row)  

创建物化视图

postgres=# \c postgres test  
You are now connected to database "postgres" as user "test".  
postgres=> create materialized view mv1 as select * from f_orig;  
SELECT 1053  

快速刷新, 物化视图必须有UK或PK.

postgres=> create unique index uk_mv1 on mv1(id);  
CREATE INDEX  
postgres=> refresh materialized view concurrently mv1;  
REFRESH MATERIALIZED VIEW  

如果DDL不想输出换行符, 修改函数如下 :

create or replace function create_ft(i_schema name, i_tbl name, i_ftschema text, i_ftname text) returns text as $$  
declare  
  v_attname name;  
  v_type text;  
  v_sql text;  
  v_nt text := '';  
  v_oid oid;  
begin  
  select oid into v_oid from pg_class where relnamespace=(select oid from pg_namespace where nspname=i_schema) and relname=i_tbl;  
  v_sql := 'create foreign table '||i_ftschema||'.'||i_ftname||' (';  
  for v_attname,v_type in SELECT a.attname,  
    pg_catalog.format_type(a.atttypid, a.atttypmod)  
    FROM pg_catalog.pg_attribute a  
    WHERE a.attrelid = v_oid AND a.attnum > 0 AND NOT a.attisdropped  
    ORDER BY a.attnum   
  LOOP  
    v_nt := v_nt||v_attname||' '||v_type||',';  
  END LOOP;  
  select regexp_replace(v_nt,',$','') into v_nt;  
  v_sql := v_sql||v_nt||$_$) server fs options(schema_name '$_$||i_schema||$_$', table_name '$_$||i_tbl||$_$');$_$;  
  return v_sql;  
end;  
$$ language plpgsql strict;  

批量输出DDL

postgres=# copy (select create_ft('public',tablename,'public','ft_'||tablename) from pg_tables where schemaname='public') to '/home/postgres/p';  
COPY 14  
postgres=> \!  
[postgres@db-172-16-3-150 ~]$ cat p  
create foreign table public.ft_p4 (ov integer,v_id integer,r_chkv numeric,p_yv numeric,r_xv numeric,dev numeric,v_slope numeric,v_inter numeric,v_r2 numeric,sampcnt integer) server fs options(schema_name 'public', table_name 'p4');  
create foreign table public.ft_tmp1 (id integer,x numeric,y numeric) server fs options(schema_name 'public', table_name 'tmp1');  
create foreign table public.ft_tmp2 (id integer,x numeric,y numeric) server fs options(schema_name 'public', table_name 'tmp2');  
create foreign table public.ft_tmp3 (id integer,x numeric,y numeric) server fs options(schema_name 'public', table_name 'tmp3');  
create foreign table public.ft_tmp4 (id integer,x numeric,y numeric) server fs options(schema_name 'public', table_name 'tmp4');  
create foreign table public.ft_p2 (ov integer,v_id integer,r_chkv numeric,p_yv numeric,r_xv numeric,dev numeric,v_slope numeric,v_inter numeric,v_r2 numeric,sampcnt integer) server fs options(schema_name 'public', table_name 'p2');  
create foreign table public.ft_zjdr (id numeric) server fs options(schema_name 'public', table_name 'zjdr');  
create foreign table public.ft_zj (id integer,cnt numeric) server fs options(schema_name 'public', table_name 'zj');  
create foreign table public.ft_t1 (c1 text,c2 numeric,c3 numeric,c4 numeric,c5 numeric,c6 numeric,c7 numeric) server fs options(schema_name 'public', table_name 't1');  
create foreign table public.ft_test (id integer,cnt numeric) server fs options(schema_name 'public', table_name 'test');  
create foreign table public.ft_orig (id integer,x numeric) server fs options(schema_name 'public', table_name 'orig');  
create foreign table public.ft_tmp (id integer,x numeric,y numeric) server fs options(schema_name 'public', table_name 'tmp');  
create foreign table public.ft_p3 (ov integer,v_id integer,r_chkv numeric,p_yv numeric,r_xv numeric,dev numeric,v_slope numeric,v_inter numeric,v_r2 numeric,sampcnt integer) server fs options(schema_name 'public', table_name 'p3');  
create foreign table public.ft_p1 (ov integer,v_id integer,r_chkv numeric,p_yv numeric,r_xv numeric,dev numeric,v_slope numeric,v_inter numeric,v_r2 numeric,sampcnt integer) server fs options(schema_name 'public', table_name 'p1');  

这样生成的代码比较紧凑, 直接执行以上生成的SQL就可以创建这些外部表了.
虽然没有import foreign schema语法简便, 但是相比手工写DDL已经好很多了.

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
2月前
|
关系型数据库 Serverless 定位技术
PostgreSQL GIS函数判断两条线有交点的函数是什么?
PostgreSQL GIS函数判断两条线有交点的函数是什么?
252 60
|
3月前
|
SQL 自然语言处理 关系型数据库
在 PostgreSQL 中使用 `REPLACE` 函数
【8月更文挑战第8天】
900 9
在 PostgreSQL 中使用 `REPLACE` 函数
|
2月前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)
|
6月前
|
SQL 分布式计算 大数据
MaxCompute产品使用合集之自建的mysql是否支持外部表
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
3月前
|
关系型数据库 PostgreSQL
PostgreSQL的null值函数
【8月更文挑战第20天】PostgreSQL的null值函数
94 3
|
3月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
401 0
|
4月前
|
SQL Oracle 关系型数据库
|
4月前
|
关系型数据库 BI 数据处理
|
5月前
|
JSON 关系型数据库 数据库
PostgreSQL中json_to_record函数的神秘面纱
`json_to_record`是PostgreSQL中的函数,用于将JSON数据转换为RECORD类型,便于查询和分析。基本用法是传入JSON数据,如`SELECT json_to_record('{"name": "张三", "age": 30}'::json);`。还可结合FUNCTION创建自定义函数,实现复杂功能。在实际应用中,它简化了对JSON格式数据的处理,例如筛选年龄大于30的用户。了解并善用此函数能提升数据库操作效率。本文由木头左分享,期待你的点赞和收藏,下次见!
PostgreSQL中json_to_record函数的神秘面纱
|
5月前
|
SQL 关系型数据库 数据库
PostgreSQL 常用函数分享
PostgreSQL 常用函数分享
48 0

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版
  • 下一篇
    无影云桌面