导入OBS桶数据到DWS集群及从DWS导出数据到OBS桶
本实践演示将样例数据上传OBS,并通过OBS外表访问OBS桶内的数据,根据需要,您也可以将OBS的数据导入DWS的目标表中,同时也可以将DWS的某张表数据导出到OBS桶。
- 导入OBS支持的数据格式:TXT、CSV、ORC、PARQUET、CARBONDATA、JSON。
- 导出OBS支持的数据格式:
- ORC、CARBONDATA、PARQUET:此种格式需要单独创建外部服务器(Foreign Server),本例描述的步骤属于此场景。
- TXT、CSV:此种方式不需要单独建外部服务器,系统默认自带gsmpp_server服务器。导出此格式的方法可参见导出CSV、TXT数据到OBS。
对象存储服务(Object storage service,简称OBS)是一种基于对象的存储服务,为客户提供海量、安全、可靠、低成本的数据存储能力。OBS可以存储任何类型的文件,适合普通用户、网站、企业和开发者。用户可以通过OBS Console或OBS Browser在任何一台连接到Internet的计算机上访问和管理存储在OBS上的数据。详情请参见OBS官网文档。
本实践预计时长:1小时,基本流程如下:
- 准备工作,创建好DWS集群和OBS桶、获取AK、SK。
- 步骤一:准备OBS数据,将预置的样例数据上传到OBS桶。
- 步骤二:创建OBS的外部服务器和外表,为导入OBS桶数据做准备。
- 步骤三:访问和导入OBS桶数据到DWS集群,通过OBS外表实现数据导入。
- 步骤四:将DWS某张表的数据导出到OBS桶,并验证只写外表不支持更新、删除数据等约束。
步骤二:创建OBS的外部服务器和外表
外部服务器(Foreign server)是数据仓库/数据库系统中用于定义和管理对外部数据源(其他数据库、文件系统等)的逻辑连接对象。它的主要作用是支持异构分布式数据的联邦访问,是实现数据整合、实时分析和数据虚拟化的重要工具。
创建OBS外部Server,通过在Server中指定OBS的Endpoint,AK、SK,才可以基于外部Server访问OBS桶数据。
- 连接数据库后,执行以下SQL语句创建外部服务器。
- 执行以下SQL,创建名为dws_data的Schema。
1
CREATE SCHEMA dws_data;
- 切换到新创的Schema下,创建外表。
注意,foldername '/obs-demo01/obs-dws/'请替换为数据文件实际存放的OBS路径,且确保OBS桶与DWS集群在同一个区域下,本例为obs-demo01桶名下的obs-dws文件夹。
SERVER obs_server为1创建的外部服务器实际的名称,本例为obs_server。1 2 3 4 5 6 7 8 9 10 11 12 13 14
CREATE FOREIGN TABLE dws_data.obs_pq_order ( order_idVARCHAR(14)PRIMARY KEY NOT ENFORCED, order_channel VARCHAR(32), order_timeTIMESTAMP, cust_codeVARCHAR(6), pay_amountDOUBLE PRECISION, real_payDOUBLE PRECISION ) SERVER obs_server OPTIONS ( foldername '/obs-demo01/obs-dws/', format 'parquet', encoding 'utf8' ) READ ONLY DISTRIBUTE BY roundrobin;
步骤三:访问和导入OBS桶数据到DWS集群
- 可通过以上步骤创建好的外表直接访问OBS桶数据。
1
SELECT * FROM dws_data.obs_pq_order;
- 也可以通过外表执行带条件的SELECT语句,例如。
1 2 3 4 5 6 7 8 9
SELECT COUNT(*) FROM dws_data.obs_pq_order; SELECT order_id, order_channel, order_time, cust_code FROM dws_data.obs_pq_order; SELECT TO_CHAR(order_time, 'Month, YYYY') AS order_month, cust_code, COUNT(*) AS order_cnt FROM dws_data.obs_pq_order WHERE DATE_PART('Year', order_time) = 2023 GROUP BY TO_CHAR(order_time, 'Month, YYYY'), cust_code HAVING COUNT(*) >= 10;
- 创建一张本地表,以通过OBS外表将数据导入DWS集群。
1 2 3 4 5 6
CREATE TABLE dws_data.dws_monthly_order ( order_monthCHAR(8), cust_codeVARCHAR(6), order_countINT, total_pay_amountDOUBLE PRECISION, total_real_payDOUBLE PRECISION );
- 您可以通过OBS外表数据统计出2023年的每月订单明细,然后将结果导入到DWS集群的本地表中。
1 2 3 4 5 6 7 8
INSERT INTO dws_data.dws_monthly_order ( order_month, cust_code, order_count , total_pay_amount, total_real_pay ) SELECT TO_CHAR(order_time, 'MON-YYYY'), cust_code, COUNT(*) , SUM(pay_amount), SUM(real_pay) FROM dws_data.obs_pq_order WHERE DATE_PART('Year', order_time) = 2023 GROUP BY TO_CHAR(order_time, 'MON-YYYY'), cust_code;
- 最后查看表数据导入情况。
1
SELECT * FROM dws_data.dws_monthly_order;
步骤四:将DWS某张表的数据导出到OBS桶
- 创建一张新的本地表。
1 2 3 4 5 6 7
CREATE TABLE dws_data.dws_order ( order_idVARCHAR(14)PRIMARY KEY, order_channel VARCHAR(32), order_timeTIMESTAMP, cust_codeVARCHAR(6), pay_amountDOUBLE PRECISION, real_payDOUBLE PRECISION );
- 插入三条数据。
1 2 3 4
INSERT INTO dws_data.dws_order VALUES ('20230627000001', 'webShop', TIMESTAMP '2023-06-27 10:00:00', 'CUST1', 1000, 1000) , ('20230627000002', 'webShop', TIMESTAMP '2023-06-27 11:00:00', 'CUST2', 5000, 5000) , ('20240309000003', 'webShop', TIMESTAMP '2024-03-09 13:00:00', 'CUST1', 2000, 2000);
- 创一张外表,用于导出数据到OBS桶。
其中foldername '/obs-demo01/obs-dws/'请替换为实际需要导出的OBS桶路径。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
CREATE FOREIGN TABLE dws_data.obs_orc_order ( order_idVARCHAR(14)PRIMARY KEY NOT ENFORCED, order_channel VARCHAR(32), order_timeTIMESTAMP, cust_codeVARCHAR(6), pay_amountDOUBLE PRECISION, real_payDOUBLE PRECISION ) SERVER obs_server OPTIONS ( foldername '/obs-demo01/obs-dws/', format 'ORC', encoding 'utf8' ) WRITE ONLY DISTRIBUTE BY roundrobin;
- 执行以下语句,将本地表数据写入OBS外表。
1 2 3
INSERT INTO dws_data.obs_orc_order ( order_id, order_channel, order_time, cust_code, pay_amount, real_pay ) SELECT order_id, order_channel, order_time, cust_code, pay_amount, real_pay FROM dws_data.dws_order;
- 查询外表,数据写入成功。
1
SELECT * FROM dws_data.obs_orc_order;
- 成功写入后,您可以登录OBS控制台,查看OBS桶对应路径下是否有数据文件存在。
- 同时可以验证下,是否允许同一张外表下额外插入数据。
1 2 3
INSERT INTO dws_data.obs_orc_order ( order_id, order_channel, order_time, cust_code, pay_amount, real_pay ) SELECT order_id, order_channel, order_time, cust_code, pay_amount, real_pay FROM dws_data.dws_order;
结果会报错:“the file path specified in the foreign table is not empty”,但如果删除外表中指定的OBS文件路径下的数据文件后,可以重新插入数据。
- 执行以下语句,验证下是否允许更新和删除外表数据。
1 2
UPDATE dws_data.obs_orc_order SET pay_amount = 3000, real_pay = 3000 WHERE order_id = '20240309000003'; DELETE FROM dws_data.obs_orc_order WHERE order_id = '20240309000003';
从显示结果看,不支持更新和删除外表数据。