如何将列添加到现有的配置单元分区表?

Vee*_*how 7 hive partitioning hive-partitions hiveddl

alter table abc add columns (stats1 map<string,string>, stats2 map<string,string>)
Run Code Online (Sandbox Code Playgroud)

我已经用上面的查询改变了我的表。但是在检查数据后,我得到了两个额外列的 NULL。我没有得到数据。

截屏

DVL*_*DVL 8

正如其他人所指出的,CASCADE这将更改所有分区的元数据。如果没有CASCADE,如果您想更改旧分区以包含新列,则需要DROP先更改旧分区,然后填充它们,INSERT OVERWRITE否则DROP将不起作用,因为元数据不会更新为新的默认元数据。

假设您已经无意外地运行了alter table abc add columns (stats1 map<string,string>, stats2 map<string,string>)CASCADE然后您的INSERT OVERWRITE旧分区没有首先被删除。数据将存储在底层文件中,但如果您从配置单元查询该表的该分区,它不会显示,因为元数据未更新。无需使用以下命令重新运行插入覆盖即可修复此问题:

  1. 运行SHOW CREATE TABLE dbname.tblname并复制添加新列之前存在的所有列定义
  2. 跑步ALTER TABLE dbname.tblname REPLACE COLUMNS ({paste in col defs besides columns to add here}) CASCADE
  3. 跑步ALTER TABLE dbname.tblname ADD COLUMNS (newcol1 int COMMENT "new col") CASCADE
  4. 很高兴所有分区的元数据都已更改 =)

作为步骤 2-3 的示例:

DROP TABLE IF EXISTS  junk.testcascade ;
CREATE TABLE junk.testcascade (
startcol INT
)
partitioned by (d int)
stored as parquet
;
INSERT INTO TABLE junk.testcascade PARTITION(d=1)
VALUES
    (1),
    (2)
;

INSERT INTO TABLE junk.testcascade PARTITION(d=2)
VALUES
    (1),
    (2)
;

SELECT * FROM junk.testcascade ;
+-----------------------+----------------+--+
| testcascade.startcol  | testcascade.d  |
+-----------------------+----------------+--+
| 1                     | 1              |
| 2                     | 1              |
| 1                     | 2              |
| 2                     | 2              |
+-----------------------+----------------+--+

 --no cascade! opps
ALTER TABLE junk.testcascade ADD COLUMNS( testcol1 int, testcol2 int) ;

INSERT OVERWRITE TABLE junk.testcascade PARTITION(d=3)
VALUES
    (1,1,1),
    (2,1,1)
;

INSERT OVERWRITE TABLE junk.testcascade PARTITION(d=2)
VALUES
    (1,1,1),
    (2,1,1)
;

--okay! because we created this table after altering the metadata
select * FROM junk.testcascade where d=3;
+-----------------------+-----------------------+-----------------------+----------------+--+
| testcascade.startcol  | testcascade.testcol1  | testcascade.testcol2  | testcascade.d  |
+-----------------------+-----------------------+-----------------------+----------------+--+
| 1                     | 1                     | 1                     | 3              |
| 2                     | 1                     | 1                     | 3              |
+-----------------------+-----------------------+-----------------------+----------------+--+

--not okay even tho we inserted =( because the metadata isnt changed
select * FROM junk.testcascade where d=2;
+-----------------------+-----------------------+-----------------------+----------------+--+
| testcascade.startcol  | testcascade.testcol1  | testcascade.testcol2  | testcascade.d  |
+-----------------------+-----------------------+-----------------------+----------------+--+
| 1                     | NULL                  | NULL                  | 2              |
| 2                     | NULL                  | NULL                  | 2              |
+-----------------------+-----------------------+-----------------------+----------------+--+

--cut back to original columns
ALTER TABLE junk.testcascade REPLACE COLUMNS( startcol int) CASCADE;

--add
ALTER table junk.testcascade ADD COLUMNS( testcol1 int, testcol2 int) CASCADE;

--it works!
select * FROM junk.testcascade where d=2; 
+-----------------------+-----------------------+-----------------------+----------------+--+
| testcascade.startcol  | testcascade.testcol1  | testcascade.testcol2  | testcascade.d  |
+-----------------------+-----------------------+-----------------------+----------------+--+
| 1                     | 1                     | 1                     | 2              |
| 2                     | 1                     | 1                     | 2              |
+-----------------------+-----------------------+-----------------------+----------------+--+
Run Code Online (Sandbox Code Playgroud)


小智 7

级联是解决方案。

询问:

ALTER TABLE dbname.table_name ADD columns (column1 string,column2 string) CASCADE; 
Run Code Online (Sandbox Code Playgroud)

这会更改表元数据的列并将相同的更改级联到所有分区元数据。 RESTRICT是默认值,将列更改限制为仅对表元数据进行更改。


lef*_*oin 5

要将列添加到分区表中,您需要重新创建分区。假设表是外部的并且数据文件已经包含新列,请执行以下操作: 1. 更改表添加列... 2. 重新创建分区。对于每个分区做 Drop 然后创建。新创建的分区模式将继承表模式。

或者,您可以删除表然后创建表并创建所有分区或只需运行MSCK REPAIR TABLE abc 命令即可恢复它们。Amazon Elastic MapReduce (EMR) 版本的 Hive 上的等效命令是:ALTER TABLE table_name RECOVER PARTITIONS. 请参阅此处的手册:恢复分区

你还在蜂巢1.1.0和更高版本可以使用CASCADE的选项ALTER TABLE ADD|REPLACE COLUMNS。请参阅此处的手册:添加列

这些建议适用于外部表。