繁体   English   中英

如何使用 for 循环将多个镶木地板文件加载到增量表中?

[英]How to load multiple parquet files into a delta table using a for loop?

我有多个镶木地板文件(大约 1000 个)。 我需要加载它们中的每一个,并将结果保存到增量表中。 我正在考虑在 pyspark 中完成 for 循环,但没有找到任何线索。 我正在使用火花 3.0。

file name example = part-00000-tid-3509510096971042864-b633a465-b62f-45b5-a5c9-61af55de541a-6264-1-c000.snappy.parquet

同样,我有 1000 个分区文件。 任何帮助,将不胜感激。

好的,就是这样。 在 Scala 中(看到太晚了),您应该能够轻松地转换为您的要求(和 pyspark)。

恕我直言,不是按顺序做事的大数据解决方案。 如果数据顺序不重要,您可以处理子集,但我认为 Delta Lake 可以反映时间旅行。

如果使用驱动程序中的 for 循环,则不会出现序列化问题。 我刚刚重新检查了 Databricks Community Edition 上的循环,如果它们存在,它应该会给出大多数序列化问题。

您将需要定制文件列表,因为它们适用于 Databricks。

相应地编码和调整:

val allFiles=dbutils.fs.ls("dbfs:/FileStore/tables/").map(_.path).filter( name => name.contains("x1") ).toList

for( file <- allFiles) {
     println("File : "+ file);
     val df = spark.read.text(file)
     df.show(false)
     df.write.format("parquet").mode(org.apache.spark.sql.SaveMode.Append).saveAsTable("SOx")
}

val df2 = spark.table("SOx")
df2.show(false)

回报:

File : dbfs:/FileStore/tables/x111.txt
+-----+
|value|
+-----+
|1    |
|2    |
|2    |
|2    |
|2    |
|2    |
+-----+

File : dbfs:/FileStore/tables/x112.txt
+-----+
|value|
+-----+
|1    |
|2    |
|2    |
|2    |
|3    |
|33   |
|33   |
+-----+

File : dbfs:/FileStore/tables/x113.txt
+-----+
|value|
+-----+
|777  |
|777  |
|666  |
+-----+


+-----+
|value|
+-----+
|1    |
|2    |
|2    |
|2    |
|3    |
|33   |
|33   |
|777  |
|777  |
|666  |
|1    |
|2    |
|2    |
|2    |
|2    |
|2    |
+-----+

当然,parquet 文件可以有 N 个部分。 不清楚你在这方面的意思,但我们无法处理 parquet 文件的单个分区文件。

在这种情况下,我使用镶木地板格式文件保存了 2 个表,以下方法确实有效。 请注意,我查找该表的路径并获取 parquet 表的所有分区文件。 我不确定这是否是你想要的。

val allPaths=dbutils.fs.ls("/user/hive/warehouse").map(_.path).filter( name => name.contains("/sox") ).toList

for( file <- allPaths) {
     println("File : "+ file);
     val df = spark.read.parquet(file)
     df.show(false)
     df.write.format("parquet").mode(org.apache.spark.sql.SaveMode.Append).saveAsTable("SOx3")
}

我无法使单个文件方面起作用。 我从未尝试过将零件单独处理到文件中,我怀疑/期望我们不应该这样做。 这对我来说很有意义。 因此,可能无法做你想做的事。 除非采用分区级别。

pyspark方法:

%python
allPaths=dbutils.fs.ls("/user/hive/warehouse")
allPathsName = map(lambda x:(x[0]),allPaths)
allPathsFiltered = [s for s in allPathsName if "/sox" in s]


for file in allPathsFiltered:
  print(file)
  df = spark.read.parquet(file)
  df.show()
  df.write.mode("append").format("parquet").saveAsTable("SOx3") 

每个分区方法是可能的 - 在 Scala 中,您可以转换为 python、pyspark:

val allPaths=dbutils.fs.ls("/user/hive/warehouse/").map(_.path).filter( name => name.contains("sox") ).toList

for( file <- allPaths) {
     println("File : "+ file)
     val allParts=dbutils.fs.ls(file).map(_.path).filter( name => name.contains("firstname=") ).toList
     println("Part : "+ allParts)
     for( part <- allParts) {
          val df = spark.read.parquet(part)
          df.show(false)
          df.write.format("parquet").mode(org.apache.spark.sql.SaveMode.Append).saveAsTable("SOx4")
     }  
}

作为最后的评论,我建议使用更大的集群。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM