Apache spark 通过databricks向配置单元外部表添加新分区
我有一个文件夹,它以前有基于Apache spark 通过databricks向配置单元外部表添加新分区,apache-spark,amazon-s3,hive,databricks,hive-partitions,Apache Spark,Amazon S3,Hive,Databricks,Hive Partitions,我有一个文件夹,它以前有基于ingestiontime的子文件夹,这也是其配置单元表中使用的原始分区 所以文件夹看起来像- s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200712230000/.... s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200711230000/.... s3://MyDevBucket/dev/myStreamingData/ingestion
ingestiontime
的子文件夹,这也是其配置单元表中使用的原始分区
所以文件夹看起来像-
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200712230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200711230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200710230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200709230000/....
........
在每个ingestiontime文件夹中,数据以PARQUET
格式显示
现在,在同一个myStreamingData
文件夹中,我正在添加另一个文件夹,该文件夹包含类似的数据,但位于名为businessname的文件夹中
所以我的文件夹结构现在看起来像-
s3://MyDevBucket/dev/myStreamingData/businessname=007/ingestiontime=20200712230000/....
s3://MyDevBucket/dev/myStreamingData/businessname=007/ingestiontime=20200711230000/....
s3://MyDevBucket/dev/myStreamingData/businessname=007/ingestiontime=20200710230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200712230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200711230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200710230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200709230000/....
........
因此,我还需要将businessname
分区中的数据添加到我当前的配置单元表中
为了实现这一点,我运行了ALTER
Query-(在Databricks上)
但我得到了这个错误-
Error in SQL statement: AnalysisException: businessname is not a valid partition column in table `default`.`gp_hive_table`.;
我在这里做错了什么
提前感谢。alter table gp\u hive\u table add partition
是将分区(数据位置,而不是新列)添加到已定义分区方案的表中,它不更改当前分区方案,只添加分区元数据,在某个位置,存在与某个分区列值对应的分区
如果要更改分区列,则需要重新创建表:
删除(检查是否为外部)表格:删除表格gp\u hive\u表格代码>
使用新分区列创建表。分区不会自动创建
现在,您可以使用altertableaddpartition
添加分区,或者使用根据目录结构自动创建分区。在执行这些命令之前,目录结构应该已经与分区方案匹配
所以,
基于@leftjoin的建议
没有businessname
作为分区之一的配置单元表,
我所做的是-
步骤1->使用分区依据(businessname long,ingestiontime long)创建配置单元表
步骤2->执行查询-MSCK REPAIR
以自动添加分区
步骤3->
现在,有ingestiontime文件夹不在文件夹businessname中,即
文件夹如-
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200712230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200711230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200710230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200709230000/....
我编写了一小段代码来获取所有这样的分区,然后对所有分区运行以下查询-
ALTER TABLE ADD PARTITION(businessname=,ingestiontime=)位置“
这解决了我的问题。既然您已经在使用Databricks,而且这是一个流式使用案例,那么您肯定应该认真考虑使用Delta Lake表
您不必处理显式的…添加分区和MSCK语句。
具有ACID属性的Delta Lake将确保正确提交数据,如果作业失败,则不会得到部分结果。一旦提交数据,用户就可以使用它(同样没有MSCK和ADD PARTITION)语句
只需在DDL中将“使用拼花地板”更改为“使用三角形”
您还可以(转换)将现有拼花地板表转换为Delta Lake表,然后开始使用INSERT、UPDATE、DELETE、MERGE-In、COPY-In、from-Spark batch和structured streaming作业。OPTIMIZE将解决小文件问题。谢谢@leftjoin,但如果您仔细查看,我的文件夹/目录结构并不统一。在所有ingestiontime=…文件夹中,我还有多个businessname/ingestiontime=…文件夹。因此,我想向已创建的配置单元表添加新分区。我不是在尝试添加新列,而是在已存在的配置单元外部表中添加新分区,即在其元数据中添加新表businessname/ingestiontime=。@GolokeshPatra(如果不尝试)ng添加新列,那么为什么在分区规范中使用两个列:partition(businessname=007,ingestiontime=20200712230000)
?使用与表DDL中定义的分区相同的分区,并将任何目录添加为分区感谢@Douglas,我也在使用Databricks Delta Lake Tables。但这里我的目的是处理和支持旧的历史数据和应用程序(如3-4年前),但您的评论给了我一个更好的主意,我会尝试让您知道。@GolokeshPatra好的,明白。我错读了前面的问题和您的回答。添加业务名称的目的是什么?是为了提高查询性能还是数据保护?我发现分区在元存储可能会影响您的读取性能。Delta Lake表(在元存储中)不需要它们。
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200712230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200711230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200710230000/....
s3://MyDevBucket/dev/myStreamingData/ingestiontime=20200709230000/....