INSERT OVERWRITE

Hologres在不同版本中逐步支持INSERT OVERWRITE功能。自Hologres V2.0版本起,通过存储过程(hg_insert_overwrite)实现该功能;自V3.1版本起,进一步支持原生INSERT OVERWRITE语法,提升了使用的便捷性和效率。

功能对比

针对不同类型的表,采用不同方案进行INSERT OVERWRITE存在一定差异,具体对比如下表所示。建议按照以下思路选择合适的方案:

  • 非分区表:两种方案均可。

  • 物理分区表:推荐使用存储过程(hg_insert_overwrite)。

  • 逻辑分区表:推荐使用原生INSERT OVERWRITE语法。

  • 物理分区表迁移到逻辑分区表:推荐使用存储过程(hg_insert_overwrite),详情请参见导入任务适配

表类型

对比项

存储过程(hg_insert_overwrite)

INSERT OVERWRITE原生语法

非分区表

支持

支持

物理分区表

导入父表

  • 支持不指定子表

  • 支持指定单个或多个子表

不支持

导入子表

支持,同普通表(非分区表)

支持,同普通表(非分区表)

逻辑分区表

导入父表(不指定分区)

不支持

不支持

导入父表(指定分区)

支持

支持

说明

若您需要通过存储过程(hg_insert_overwrite)或原生INSERT OVERWRITE语法进行数据写入,请确保您的实例版本符合要求。申请实例版本升级详情,请参见实例升级。如您暂时不方便升级,也可使用临时表方式实现INSERT OVERWRITE功能详情,请参见使用临时表实现INSERT OVERWRITE功能

使用原生INSERT OVERWRITE

功能说明

  • Hologres V3.1版本起支持原生INSERT OVERWRITE语法。

  • 原生INSERT OVERWRITE语法针对不同类型的表:

    • 支持普通表,即非分区表。

    • 支持物理分区表的分区子表(做普通表处理),不支持物理分区表的分区父表。

    • 支持逻辑分区表,但必须指定分区。

使用限制

原生INSERT OVERWRITE语法会默认开启混合DML事务:SET hg_experimental_enable_transaction = on;,Hologres的事务能力详情,请参见SQL事务能力

  • 同一事务中,不支持INSERT OVERWRITEDDL混合。

  • 同一事务中,所有DML将在事务完成时,即执行COMMIT时,真正提交。

命令格式

INSERT OVERWRITE <target_table_name> 
  [ PARTITION (<partition_key> = '<partition_value>') [, ...]]
  VALUES ( <expression>  [, ...] ) [, ...] | <query>;

参数说明

参数

是否必填

说明

target_table_name

目标表名。

partition_keypartition_value

分区键和分区值,仅支持逻辑分区表。

说明

如果target_table_name是逻辑分区表,必须指定分区partition_keypartition_value参数。

expression

要赋予目标表对应列的表达式或者值。

query

标准的SELECT语句,并将查询结果覆写至target_table_name表。

说明

如果target_table_name是逻辑分区表,指定了分区partition_value,若query查询结果包含部分不属于指定分区的数据,将自动忽略;若query查询结果均未包含对应分区的数据,则该分区将被清空。

使用示例

使用原生INSERT OVERWRITE语法导入非分区表

-- 创建表A作为目标表
CREATE TABLE public.tablea (
    cid INTEGER NOT NULL,
    cname TEXT,
    code INTEGER
    ,PRIMARY KEY (cid)
);

-- 创建表B作为数据输入
CREATE TABLE public.tableb (
    cid INTEGER NOT NULL,
    cname TEXT,
    code INTEGER
    ,PRIMARY KEY (cid)
);

INSERT INTO public.tableb VALUES(1,'aaa',10001),(2,'bbb','10002');

-- 使用原生Insert Overwrite语法将表B数据插入表A
INSERT OVERWRITE public.tablea SELECT * FROM public.tableb;

使用原生Insert Overwrite语法导入逻辑分区表

-- 创建表A作为目标逻辑分区表
CREATE TABLE public.tablea(
  a TEXT , 
  b INT, 
  c TIMESTAMP, 
  d TEXT,
  ds TEXT,
  PRIMARY KEY(ds,b)
  )
  LOGICAL PARTITION BY LIST(ds);

-- 创建物理分区表B作为数据输入
BEGIN;
CREATE TABLE public.tableb(
  a TEXT, 
  b INT, 
  c TIMESTAMP, 
  d TEXT,
  ds TEXT,
  PRIMARY KEY(ds,b)
  )
  PARTITION BY LIST(ds);
CREATE TABLE public.holo_child_3a PARTITION OF public.tableb FOR VALUES IN('20201215');
CREATE TABLE public.holo_child_3b PARTITION OF public.tableb FOR VALUES IN('20201216');
CREATE TABLE public.holo_child_3c PARTITION OF public.tableb FOR VALUES IN('20201217');
COMMIT;

INSERT INTO public.holo_child_3a VALUES('a',1,'2034-10-19','a','20201215');
INSERT INTO public.holo_child_3b VALUES('b',2,'2034-10-20','b','20201216');
INSERT INTO public.holo_child_3c VALUES('c',3,'2034-10-21','c','20201217');

-- 使用原生Insert Overwrite语法将表B数据插入表A
INSERT OVERWRITE public.tablea PARTITION (ds = '20201215') SELECT * FROM public.tableb WHERE ds='20201215';

使用存储过程实现INSERT OVERWRITE功能

功能说明

  • HologresV3.1版本开始,支持逻辑分区表,存储过程(hg_insert_overwrite)也支持逻辑分区表,但在使用时需要明确指定分区。

  • Hologres V3.0版本增强了hg_insert_overwrite能力,支持通过INSERT OVERWRITE命令直接导入数据至分区父表。

  • Hologres V2.0.15版本开始,支持通过set hg_experimental_hg_insert_overwrite_enable_view=on;命令开启GUC,实现向有视图依赖的表中导入数据;暂不支持向有物化视图依赖的表中导入数据。

    Hologres V3.0版本开始,无需设置上述GUC,即可支持向有视图依赖的表中导入数据;暂不支持向有物化视图依赖的表中导入数据。

  • 对于Hologres V2.0.11以前的版本,导入失败需要手动清理临时表;自V2.0.11版本开始,系统会自动清理临时表。

使用限制

  • 如果选择部分字段导入,字段顺序需要与源表保持一致且一一对应。

  • 由于hg_insert_overwrite需要以表Owner的身份新建一张临时表,因此仅Superuser和表的Owner有权限执行hg_insert_overwrite操作。

  • 目标表的分区键支持INT、TEXTVARCHAR类型。

  • Hologres V3.0版本起,明确要求不能在事务中使用hg_insert_overwrite,执行会报错。

    说明

    在旧版本的事务中使用存储过程(hg_insert_overwrite),特定情况下会发生死锁、卡住等潜在问题,而新版本对此将采取更加严格的措施。

  • Hologres V3.1版本起,存储过程(hg_insert_overwrite)中select_query指定列的数量、数据类型均需和target_table的列严格对应,否则会报错“error: table "hg_alias" has x columns available but x columns specified”,或“error: column xx is of type xxx but expression is of type xxx”

行为变更

Hologres V3.0版本起,存储过程(hg_insert_overwrite)有如下行为变更:

  • 仅有target_tableselect_query两个入参时,且目标表是分区父表,则Hologres V3.0版本前会直接报错。自Hologres V3.0版本起,存在以下可能:

    • select_query执行结果对应的分区子表都已存在时,写入成功。

    • select_query执行结果对应的分区子表不存在时,可能报错。

  • 如果存储过程(hg_insert_overwrite)执行中途取消,需注意:

    • Hologres V3.0版本起,需要执行如下SQL清理临时表。

      --- 删除before_time之前系统创建的临时表
      CALL hg_clean_insert_overwrite_tmp_tables(before_time::timestamptz); 
    • Hologres V3.0版本前,不需要清理临时表。

命令格式

-- V3.0版本前的hg_insert_overwrite语法
CALL hg_insert_overwrite('<target_table>' regclass, ['<partition_value>' TEXT], '<sql>' TEXT);

-- V3.0及以上版本的hg_insert_overwrite语法
CALL hg_insert_overwrite('<target_table>' regclass, ['<partition_value>' ARRAY], '<sql>' TEXT, ['<auto_create_partition>' BOOLEAN]);

参数说明

说明

Hologres V3.0版本起,hg_insert_overwrite语句中的partition_value数据类型改为ARRAY类型,即支持写入物理分区父表并指定多个物理分区子表。您仍可使用TEXT类型作为partition_value的入参,但此时只支持写入一张物理分区子表。

参数

说明

target_table

Hologres的内部表。

即数据目标存储表,表必须已经存在。

partition_value

分区表的分区值。

  • V3.0版本前,如果target_table为物理分区父表,则必须指定partition_value(TEXT类型),即只支持导入一张分区子表。如果分区子表不存在,则会自动创建。

  • V3.0版本起,如果target_table为物理分区父表,可选是否指定partition_value(ARRAYTEXT类型),具体行为见下文。

  • V3.1版本起,如果target_table为逻辑分区表,必须指定partition_value(ARRAYTEXT类型)。

sql

标准的SELECT语句。

可用来查询MaxCompute或者Hologres的表,需确保SELECT出来的分区字段值必须完全等于partition_value。如果SQL语句中含有单引号(''),需要通过$$sql$$改写sql,以自动实现单引号转义。

  • V3.0版本前,需确保SELECT出的分区字段值必须完全等于partition_value

  • V3.0版本起,SELECT出的分区字段值可以不完全等于partition_value具体行为见下文。

auto_create_partition

是否自动创建分区。仅V3.0及以上版本支持该参数,并且仅适用于物理分区表生效,逻辑分区表忽略此参数。

  • TRUE:当sql的执行结果中包含不存在的分区子表时,自动创建对应的物理分区子表。

  • FALSE(默认值):当sql的执行结果中包含不存在的分区子表时,不自动创建对应的物理分区子表。

V3.0版本起,针对INSERT OVERWRITE分区父表,即target_table为分区父表的情况,不同参数设置的行为如下:

  • 物理分区表

    参数取值

    auto_create_partition

    TRUE

    FALSE

    partition_value

    不指定

    • sql执行结果对应的target_table分区,全部执行数据覆写。如果有不存在的分区子表,则先自动创建分区。

    • sql执行结果无关的target_table分区,忽略。

    • sql执行结果中,如果对应的target_table分区都存在:

      • 执行结果对应的target_table分区,全部执行数据覆写。

      • 与执行结果无关的target_table分区,忽略。

    • sql执行结果中,如果有对应的target_table分区不存在,则直接报错,其余已存在的分区也不执行覆写。

    指定

    对于partition_value指定的target_table分区:

    • 如果分区实际不存在:自动创建分区。

    • sql执行结果对应的分区:执行数据覆写。

    • sql执行结果无关的分区:直接清空。

    对于partition_value未指定的target_table分区:

    • sql执行结果如果包含未指定的分区:不处理。

    • sql执行结果无关的分区:不处理。

    • 对于partition_value指定的target_table分区:

      • 如果分区实际不存在:直接报错,其余分区也不执行覆写。

      • sql执行结果对应的分区:执行数据覆写。

      • sql执行结果无关的分区:直接清空。

    • 对于partition_value未指定的target_table分区:

      • sql执行结果如果包含未指定的分区:不处理。

      • sql执行结果无关的分区:不处理。

  • 逻辑分区表:

    逻辑分区表不涉及自动创建分区(auto_create_partition),忽略此参数。

    参数取值

    说明

    partition_value

    不指定

    不支持。

    指定

    对于partition_value指定的target_table分区:

    • sql执行结果对应的分区:执行数据覆写。

    • sql执行结果无关的分区:直接清空。

    对于partition_value未指定的target_table分区:

    • sql执行结果如果包含未指定的分区:不处理。

    • sql执行结果无关的分区:不处理。

使用示例

示例1:使用存储过程将Hologres内部表数据导入Hologres物理分区表

-- 创建表A作为目标表
BEGIN;
CREATE TABLE public.tablea (
    cid INTEGER NOT NULL,
    cname TEXT,
    code INTEGER
    ,PRIMARY KEY (cid)
);

CALL set_table_property('public.tablea', 'orientation', 'column');
CALL set_table_property('public.tablea', 'storage_format', 'orc');
CALL set_table_property('public.tablea', 'bitmap_columns', 'cname');
CALL set_table_property('public.tablea', 'dictionary_encoding_columns', 'cname:auto');
CALL set_table_property('public.tablea', 'distribution_key', 'cid');
CALL set_table_property('public.tablea', 'time_to_live_in_seconds', '3153600000');
COMMIT;

-- 创建表B作为数据输入
CREATE TABLE public.tableb (
    cid INTEGER NOT NULL,
    cname TEXT,
    code INTEGER
    ,PRIMARY KEY (cid)
);

INSERT INTO public.tableb VALUES(1,'aaa',10001),(2,'bbb','10002');

-- 使用hg_insert_overwrite 将表B数据插入表A
CALL hg_insert_overwrite('public.tablea' , 'SELECT * FROM public.tableb');

示例2:使用存储过程将Hologres内部表数据导入Hologres物理分区表

-- 创建表A作为目标表
BEGIN;
CREATE TABLE public.tableA(
  a TEXT , 
  b INT, 
  c TIMESTAMP, 
  d TEXT,
  ds TEXT,
  PRIMARY key(ds,b)
  )
  PARTITION BY LIST(ds);
CALL set_table_property('public.tableA', 'orientation', 'column');
CREATE TABLE public.holo_child_1 PARTITION OF public.tableA FOR VALUES IN('20201215');
CREATE TABLE public.holo_child_2 PARTITION OF public.tableA FOR VALUES IN('20201216');
CREATE TABLE public.holo_child_3 PARTITION OF public.tableA FOR VALUES IN('20201217');
COMMIT;

-- 创建表B作为数据输入
BEGIN;
CREATE TABLE public.tableB(
  a TEXT, 
  b INT, 
  c TIMESTAMP, 
  d TEXT,
  ds TEXT,
  PRIMARY key(ds,b)
  )
  PARTITION BY LIST(ds);
CALL set_table_property('public.tableB', 'orientation', 'column');
CREATE TABLE public.holo_child_3a PARTITION OF public.tableB FOR VALUES IN('20201215');
CREATE TABLE public.holo_child_3b PARTITION OF public.tableB FOR VALUES IN('20201216');
CREATE TABLE public.holo_child_3c PARTITION OF public.tableB FOR VALUES IN('20201217');
COMMIT;

INSERT INTO public.holo_child_3a VALUES('a',1,'2034-10-19','a','20201215');
INSERT INTO public.holo_child_3b VALUES('b',2,'2034-10-20','b','20201216');
INSERT INTO public.holo_child_3c VALUES('c',3,'2034-10-21','c','20201217');

-- 使用insert overwrite 将表B数据插入表A
CALL hg_insert_overwrite('public.tableA' , '20201215',$$SELECT * FROM public.tableB WHERE ds='20201215'$$);

示例3:使用存储过程将MaxCompute非分区表数据导入Hologres非分区表

-- 在MaxCompute中创建一张非分区表。示例选用MaxCompute公告数据集public_data项目下的customer表数据,其表DDL如下。
CREATE TABLE IF NOT EXISTS public_data.customer(
  c_customer_sk BIGINT,
  c_customer_id STRING,
  c_current_cdemo_sk BIGINT,
  c_current_hdemo_sk BIGINT,
  c_current_addr_sk BIGINT,
  c_first_shipto_date_sk BIGINT,
  c_first_sales_date_sk BIGINT,
  c_salutation STRING,
  c_first_name STRING,
  c_last_name STRING,
  c_preferred_cust_flag STRING,
  c_birth_day BIGINT,
  c_birth_month BIGINT,
  c_birth_year BIGINT,
  c_birth_country STRING,
  c_login STRING,
  c_email_address STRING,
  c_last_review_date STRING,
  useless STRING);

-- 在Hologres中创建一张外部表,用于映射MaxCompute中的源头数据表。
CREATE FOREIGN TABLE customer (
    "c_customer_sk" INT8,
    "c_customer_id" TEXT,
    "c_current_cdemo_sk" INT8,
    "c_current_hdemo_sk" INT8,
    "c_current_addr_sk" INT8,
    "c_first_shipto_date_sk" INT8,
    "c_first_sales_date_sk" INT8,
    "c_salutation" TEXT,
    "c_first_name" TEXT,
    "c_last_name" TEXT,
    "c_preferred_cust_flag" TEXT,
    "c_birth_day" INT8,
    "c_birth_month" INT8,
    "c_birth_year" INT8,
    "c_birth_country" TEXT,
    "c_login" TEXT,
    "c_email_address" TEXT,
    "c_last_review_date" TEXT,
    "useless" TEXT
)
SERVER odps_server
OPTIONS (project_name 'public_data', table_name 'customer');

-- 在Hologres中建立一张内部表(以列存表为例),用于接收MaxCompute源头表数据。
BEGIN;
CREATE TABLE public.holo_customer (
 "c_customer_sk" INT8,
 "c_customer_id" TEXT,
 "c_current_cdemo_sk" INT8,
 "c_current_hdemo_sk" INT8,
 "c_current_addr_sk" INT8,
 "c_first_shipto_date_sk" INT8,
 "c_first_sales_date_sk" INT8,
 "c_salutation" TEXT,
 "c_first_name" TEXT,
 "c_last_name" TEXT,
 "c_preferred_cust_flag" TEXT,
 "c_birth_day" INT8,
 "c_birth_month" INT8,
 "c_birth_year" INT8,
 "c_birth_country" TEXT,
 "c_login" TEXT,
 "c_email_address" TEXT,
 "c_last_review_date" TEXT,
 "useless" TEXT
);
COMMIT;

-- 导入数据至Hologres。
IMPORT FOREIGN SCHEMA <project_name> LIMIT TO
(customer) FROM server odps_server INTO PUBLIC options(if_table_exist 'update');--更新外部表
SELECT pg_sleep(30);--等待一些时间再导入Hologres,以防Hologres meta信息更新缓存慢导致的数据不一致而同步不成功

CALL  hg_insert_overwrite('holo_customer', 'SELECT * FROM customer where c_birth_year > 1980');

-- 在Hologres中查询MaxCompute源表中的数据。
SELECT * FROM holo_customer limit 10;

示例4:使用存储过程将MaxCompute分区表数据导入Hologres物理分区子表

-- 在MaxCompute中创建一张分区表。
DROP TABLE IF EXISTS odps_sale_detail;

CREATE TABLE IF NOT EXISTS odps_sale_detail 
(
    shop_name STRING
    ,customer_id STRING
    ,total_price DOUBLE
)
PARTITIONED BY 
(
    sale_date STRING
)
;

-- 向源表增加分区20210815
ALTER TABLE odps_sale_detail ADD IF NOT EXISTS PARTITION(sale_date='20210815')
;

-- 向分区写入数据
INSERT OVERWRITE TABLE odps_sale_detail PARTITION(sale_date='20210815') VALUES 
('s1','c1',100.1),
('s2','c2',100.2),
('s3','c3',100.3)
;

-- 在Hologres中创建一张外部表,用于映射MaxCompute中的源头数据表。
DROP FOREIGN TABLE IF EXISTS odps_sale_detail;

-- 创建外部表
IMPORT FOREIGN SCHEMA <maxcompute_project> LIMIT TO
(
    odps_sale_detail
) 
FROM SERVER odps_server INTO public 
OPTIONS(if_table_exist 'error',if_unsupported_type 'error');

-- 在Hologres中建立一张内部表,用于接收MaxCompute源头表数据。
DROP TABLE IF EXISTS holo_sale_detail;

-- 创建Hologres分区表(内部表)
BEGIN ;
CREATE TABLE IF NOT EXISTS holo_sale_detail
(
    shop_name TEXT
    ,customer_id TEXT 
    ,total_price FLOAT8
    ,sale_date TEXT
)
PARTITION BY LIST(sale_date);
COMMIT;

-- 导入数据至Hologres。
CALL hg_insert_overwrite('holo_sale_detail', '20210815', $$SELECT * FROM public.odps_sale_detail WHERE sale_date='20210815'$$);

-- 在Hologres中查询MaxCompute源表中的数据。
SELECT * FROM holo_sale_detail;

示例5:使用存储过程将MaxCompute分区表数据导入Hologres物理分区父表

-- 在MaxCompute中创建一张分区表。
DROP TABLE IF EXISTS odps_sale_detail;

CREATE TABLE IF NOT EXISTS odps_sale_detail 
(
    shop_name STRING
    ,customer_id STRING
    ,total_price DOUBLE
)
PARTITIONED BY 
(
    sale_date STRING
)
;

-- 向源表增加分区20210815和20210816
ALTER TABLE odps_sale_detail ADD IF NOT EXISTS PARTITION(sale_date='20210815')
;
ALTER TABLE odps_sale_detail ADD IF NOT EXISTS PARTITION(sale_date='20210816')
;

-- 向分区写入数据
INSERT OVERWRITE TABLE odps_sale_detail PARTITION(sale_date='20210815') VALUES 
('s1','c1',100.1),
('s2','c2',100.2),
('s3','c3',100.3)
;
INSERT OVERWRITE TABLE odps_sale_detail PARTITION(sale_date='20210816') VALUES 
('s1','c1',100.1),
('s2','c2',100.2),
('s3','c3',100.3)
;

-- 在Hologres中创建一张外部表,用于映射MaxCompute中的源头数据表。
DROP FOREIGN TABLE IF EXISTS odps_sale_detail;

-- 创建外部表
IMPORT FOREIGN SCHEMA <maxcompute_project> LIMIT TO
(
    odps_sale_detail
) 
FROM SERVER odps_server INTO public 
OPTIONS(if_table_exist 'error',if_unsupported_type 'error');

-- 在Hologres中建立一张内部表,用于接收MaxCompute源头表数据。
DROP TABLE IF EXISTS holo_sale_detail;

-- 创建Hologres分区表(内部表)
BEGIN ;
CREATE TABLE IF NOT EXISTS holo_sale_detail
(
    shop_name TEXT
    ,customer_id TEXT 
    ,total_price FLOAT8
    ,sale_date TEXT
)
PARTITION BY LIST(sale_date);
COMMIT;

-- 导入数据至Hologres。不指定分区子表且auto_create_partition为TRUE,系统会自动创建两个分区子表并导入数据
CALL hg_insert_overwrite ('holo_sale_detail', $$SELECT * FROM public.odps_sale_detail$$, TRUE);

-- 在Hologres中查询数据。
SELECT * FROM holo_sale_detail;
说明

maxcompute_project:MaxCompute分区表所在的项目名称。

使用临时表实现INSERT OVERWRITE功能

命令格式

您可以使用如下SQL语句实现INSERT OVERWRITE的功能。

BEGIN ;

-- 清理潜在的临时表
DROP TABLE IF EXISTS <table_new>;

-- 创建临时表
SET hg_experimental_enable_create_table_like_properties=on;
CALL HG_CREATE_TABLE_LIKE ('<table_new>', 'select * from <table>');

COMMIT ;

-- 向临时表插入数据
INSERT INTO <table_new> [( <column> [, ...] )]
VALUES ( {<expression>}  [, ...] )
[, ...] | <query>}

ANALYZE <table_new>;

BEGIN ;

-- 删除旧表
DROP TABLE IF EXISTS  <table>;

-- 临时表改名
ALTER TABLE <table_new> RENAME TO <table>;

COMMIT ;

参数说明

参数

说明

table_new

新创建的临时表名称。

表名称也可以使用Schema.Table格式。

table

已存在的表名称。

表名称也可以使用Schema.Table格式。

临时表DDL

创建临时表有如下两种方式。

  • 通过复制已有表创建新表的结构

    SET hg_experimental_enable_create_table_like_properties=on;
    CALL HG_CREATE_TABLE_LIKE ('<table_new>', 'select * from <table>');
  • 新建表的结构

    CREATE TABLE IF NOT EXISTS <table_new> ([
      {
       column_name column_type [column_constraints, [...]]
       | table_constraints
       [, ...]
      }
    ]);
    
    CALL set_table_property('<table_new>', property, value);

使用示例

MaxComputeHologres的非分区表导入数据

MaxComputeHologres导入数据的场景中,希望将数据全量覆盖,常见于离线加工后的结果表导出为线上服务表。此场景使用示例如下所示,将MaxCompute中的odps_region_10g表的数据写入Hologresregion表中,且将Hologresregion表的数据全量覆盖。

BEGIN ;

-- 清理潜在的临时表
DROP TABLE IF EXISTS public.region_new;

-- 创建临时表
SET hg_experimental_enable_create_table_like_properties=on;
CALL HG_CREATE_TABLE_LIKE ('public.region_new', 'select * from public.region');
COMMIT ;

-- 向临时表插入数据
INSERT INTO public.region_new
SELECT *
FROM public.odps_region_10g;

ANALYZE public.region_new;

BEGIN ;

-- 删除旧表
DROP TABLE IF EXISTS public.region;

-- 临时表改名
ALTER TABLE IF EXISTS public.region_new RENAME TO region;

COMMIT ;

MaxComputeHologres的分区表导入数据

在每天定期更新MaxCompute分区表的数据,且需要将MaxCompute分区表向Hologres的分区表导入数据的场景中,希望将数据全量覆盖,实现离线数据对实时数据的修正。此场景使用示例如下所示,将MaxCompute中的odps_lineitem_10g表的数据写入Hologreslineitem表中,且全量覆盖Hologreslineitem表的数据,两个表都是按照ds字段按天分区。

BEGIN ;

-- 清理潜在的临时表
DROP TABLE IF EXISTS public.lineitem_new_20210101;

-- 创建临时表
SET hg_experimental_enable_create_table_like_properties=on;
CALL HG_CREATE_TABLE_LIKE ('public.lineitem_new_20210101', 'select * from public.lineitem');
COMMIT ;

-- 向临时表插入数据
INSERT INTO public.lineitem_new_20210101
SELECT *
FROM public.odps_lineitem_10g
WHERE DS = '20210101'

ANALYZE public.lineitem_new_20210101;

BEGIN ;

-- 删除旧分区
DROP TABLE IF EXISTS public.lineitem_20210101;

-- 临时表改名
ALTER TABLE public.lineitem_new_20210101 RENAME TO lineitem_20210101;

-- 将临时表绑定至指定分区表
ALTER TABLE public.lineitem ATTACH PARTITION lineitem_20210101 FOR VALUES IN ('20210101');

COMMIT ;

HologresMaxCompute的非分区表导入数据

如果您需要从HologresMaxCompute的非分区表导入数据,建议采用临时表导入的方式,导入完成后将临时表改名为正式表即可。此场景使用示例如下所示,将Hologresholotable表的数据写入MaxComputemc_holotable表中,且将MaxComputemc_holotable表数据全量覆盖。

-- 在MC中创建目标表的临时表
CREATE  TABLE if not exists mc_holotable_temp(
    age INT,
    job STRING,
    name STRING
);

-- 在Hologres中创建临时表的映射
CREATE FOREIGN TABLE "public"."mapping_holotable_temp" (
 "age" INT,
 "job" TEXT,
 "name" TEXT
)
SERVER odps_server
OPTIONS (project_name 'DLF_test',table_name 'mc_holotable_temp');
-- 在Hologres中更新原始表
UPDATE holotable SET "job" = 'president' WHERE "name" = 'Lily';
-- 将更新后的数据写入临时表的映射
INSERT INTO mapping_holotable_temp SELECT * FROM holotable;

-- 在MaxCompute中删除旧的目标表
DROP TABLE IF EXISTS mc_holotable;
-- 临时表更名为目标表即可
ALTER TABLE mc_holotable_temp RENAME TO mc_holotable;

导入数据支持部分导入和全表导入两种方式:

  • 导出部分字段示例:

    INSERT INTO mapping_holotable_temp
    SELECT x,x,x FROM holotable;  --x,x,x可以替换为您需要导出的字段名
  • 导出全部字段示例:

    INSERT INTO mapping_holotable_temp
    SELECT * FROM holotable;