alter table abc add columns (stats1 map<string,string>, stats2 map<string,string>)
我用上面的查询改变了我的表格。但是在检查数据之后,我得到了两个额外列的NULL。我没有收到数据。
答案 0 :(得分:2)
要将列添加到分区表中,您需要重新创建分区。 假设表是外部的,并且数据文件已包含新列,请执行以下操作: 1.更改表添加列... 2.重新创建分区。对于每个分区,请执行Drop然后创建。新创建的分区模式将继承表模式。
或者,您可以删除表,然后创建表并创建所有分区,或者只需运行MSCK REPAIR TABLE abc
命令即可恢复它们。 Amazon Elastic MapReduce(EMR)的Hive版本上的等效命令是:ALTER TABLE table_name RECOVER PARTITIONS
。
请参阅此处的手册:RECOVER PARTITIONS
同样在Hive 1.1.0及更高版本中,您可以使用CASCADE
的{{1}}选项。请参阅此处的手册:ADD COLUMN
这些建议适用于外部表格。
答案 1 :(得分:2)
CASCADE是解决方案。
查询:
ALTER TABLE dbname.table_name ADD columns (column1 string,column2 string) CASCADE;
这会更改表格元数据的列,并将相同的更改级联到所有分区元数据。
RESTRICT
是默认设置,仅限列更改表元数据。
答案 2 :(得分:0)
正如其他人所指出的,CASCADE
将更改所有分区的元数据。如果没有CASCADE
,则要更改旧分区以包括新列,则需要先DROP
个旧分区,然后再填充它们,INSERT OVERWRITE
不带{{1} }无效,因为元数据不会更新为新的默认元数据。
比方说,您已经无意中运行了DROP
而没有alter table abc add columns (stats1 map<string,string>, stats2 map<string,string>)
,然后您CASCADE
了一个旧分区而没有先删除。数据将存储在基础文件中,但是如果您从蜂巢中查询该分区的表,该数据将不会显示,因为元数据没有更新。可以解决此问题,而不必使用以下命令重新运行插入覆盖:
INSERT OVERWRITE
并复制添加新列之前存在的所有列定义SHOW CREATE TABLE dbname.tblname
ALTER TABLE dbname.tblname REPLACE COLUMNS ({paste in col defs besides columns to add here}) CASCADE
作为第2-3步的示例:
ALTER TABLE dbname.tblname ADD COLUMNS (newcol1 int COMMENT "new col") CASCADE
答案 3 :(得分:0)
仅当您的数据已分区并且您知道最新分区的位置时,此解决方案才有效。在这种情况下,您可以执行以下操作,而不是执行恢复分区或修复这是一项昂贵的操作:
发布scala代码以供参考:
def updateMetastoreColumns(spark: SparkSession, partitionedTablePath: String, toUpdateTableName: String): Unit = {
//fetch all column names along with their corresponding datatypes from latest partition
val partitionedTable = spark.read.orc(partitionedTablePath)
val partitionedTableColumns = partitionedTable.columns zip partitionedTable.schema.map(_.dataType.catalogString)
//fetch all column names along with their corresponding datatypes from currentTable
val toUpdateTable = spark.read.table(toUpdateTableName)
val toUpdateTableColumns = toUpdateTable.columns zip toUpdateTable.schema.map(_.dataType.catalogString)
//check if new columns are present in newer partition
val diffColumns = partitionedTableColumns.diff(toUpdateTableColumns)
//update the metastore with new column info
diffColumns.foreach {column: (String, String) => {
spark.sql(s"ALTER TABLE ${toUpdateTableName} ADD COLUMNS (${column._1} ${column._2})")
}}
}
这将帮助您动态查找添加到较新分区中的最新列,并动态地将其更新到您的metastore。