文档首页/ 数据仓库服务 DWS/ 最佳实践/ 导入导出/ 导入OBS桶数据到DWS集群及从DWS导出数据到OBS桶
更新时间:2025-08-22 GMT+08:00

导入OBS桶数据到DWS集群及从DWS导出数据到OBS桶

本实践演示将样例数据上传OBS,并通过OBS外表访问OBS桶内的数据,根据需要,您也可以将OBS的数据导入DWS的目标表中,同时也可以将DWS的某张表数据导出到OBS桶。

  • 导入OBS支持的数据格式TXT、CSV、ORC、PARQUET、CARBONDATA、JSON
  • 导出OBS支持的数据格式

对象存储服务(Object storage service,简称OBS)是一种基于对象的存储服务,为客户提供海量、安全、可靠、低成本的数据存储能力。OBS可以存储任何类型的文件,适合普通用户、网站、企业和开发者。用户可以通过OBS Console或OBS Browser在任何一台连接到Internet的计算机上访问和管理存储在OBS上的数据。详情请参见OBS官网文档

本实践预计时长:1小时,基本流程如下:

准备工作

  • 已创建数据仓库服务DWS,参见创建集群
  • 已创建OBS桶,注意与DWS在同一个区域下,例如桶名为obs-demo01(如果提示桶名已被占用,则命名为obs-demo02,以此类推),参见OBS文档
  • 已获取账户的AK和SK,用于访问OBS桶数据,参见访问密钥

步骤一:准备OBS数据

  1. 下载数据样例文件
  2. 登录OBS控制台,单击桶列表中已创建好的dws-demo01桶名称。
  3. 左侧选择“对象”,单击“新建文件夹”,命名为obs-dws。
  4. 进入到obs-dws的文件夹下,单击“上传对象”,将1下载的样例文件上传到obs-dws文件夹下。
  5. 获取OBS的Endpoint。

    1. 回到obs-dwst桶名的主页面,左侧选择“概览”。
    2. 在“域名信息”中记录Endpoint,例如obs.ap-southeast-1.myhuaweicloud.com

步骤二:创建OBS的外部服务器和外表

外部服务器(Foreign server)是数据仓库/数据库系统中用于定义和管理对外部数据源(其他数据库、文件系统等)的逻辑连接对象。它的主要作用是支持异构分布式数据的联邦访问,是实现数据整合、实时分析和数据虚拟化的重要工具。

创建OBS外部Server,通过在Server中指定OBS的Endpoint,AK、SK,才可以基于外部Server访问OBS桶数据。

  1. 连接数据库后,执行以下SQL语句创建外部服务器。

    其中ADDRESS填写5获取地址,ACCESS_KEY、 SECRET_ACCESS_KEY分别填写准备工作中获取账户的AK和SK。
    1
    2
    3
    4
    5
    6
    7
    CREATE SERVER obs_server FOREIGN DATA WRAPPER DFS_FDW 
    OPTIONS ( 
      ADDRESS 'obs.aaaaa.bbbbb.com', 
      ACCESS_KEY 'xxxxxxxxx', 
      SECRET_ACCESS_KEY 'yyyyyyyyyyyyy', 
      TYPE 'OBS'
      );
    

  2. 执行以下SQL,创建名为dws_data的Schema。

    1
    CREATE SCHEMA dws_data;
    

  3. 切换到新创的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集群

  1. 可通过以上步骤创建好的外表直接访问OBS桶数据。

    1
    SELECT * FROM dws_data.obs_pq_order;
    

  2. 也可以通过外表执行带条件的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;
    

  3. 创建一张本地表,以通过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 );
    

  4. 您可以通过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;
    

  5. 最后查看表数据导入情况。

    1
    SELECT * FROM dws_data.dws_monthly_order;
    

步骤四:将DWS某张表的数据导出到OBS桶

  1. 创建一张新的本地表。

    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 );
    

  2. 插入三条数据。

    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);
    

  3. 创一张外表,用于导出数据到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;
    

  4. 执行以下语句,将本地表数据写入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;
    

  5. 查询外表,数据写入成功。

    1
    SELECT * FROM dws_data.obs_orc_order;
    

  6. 成功写入后,您可以登录OBS控制台,查看OBS桶对应路径下是否有数据文件存在。
  7. 同时可以验证下,是否允许同一张外表下额外插入数据。

    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文件路径下的数据文件后,可以重新插入数据。

  8. 执行以下语句,验证下是否允许更新和删除外表数据。

    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';
    

    从显示结果看,不支持更新和删除外表数据。