通用文件源选项

这些通用选项/配置仅在使用基于文件的源时有效:parquet、orc、avro、json、csv、text。

请注意,以下示例中使用的目录层次结构为

dir1/
 ├── dir2/
 │    └── file2.parquet (schema: <file: string>, content: "file2.parquet")
 └── file1.parquet (schema: <file, string>, content: "file1.parquet")
 └── file3.json (schema: <file, string>, content: "{'file':'corrupt.json'}")

忽略损坏文件

Spark 允许您使用配置 spark.sql.files.ignoreCorruptFiles 或数据源选项 ignoreCorruptFiles 来忽略从文件中读取数据时遇到的损坏文件。当设置为 true 时,Spark 作业将在遇到损坏文件时继续运行,并且已读取的内容仍将被返回。

要忽略读取数据文件时遇到的损坏文件,您可以使用

# enable ignore corrupt files via the data source option
# dir1/file3.json is corrupt from parquet's view
test_corrupt_df0 = spark.read.option("ignoreCorruptFiles", "true")\
    .parquet("examples/src/main/resources/dir1/",
             "examples/src/main/resources/dir1/dir2/")
test_corrupt_df0.show()
# +-------------+
# |         file|
# +-------------+
# |file1.parquet|
# |file2.parquet|
# +-------------+

# enable ignore corrupt files via the configuration
spark.sql("set spark.sql.files.ignoreCorruptFiles=true")
# dir1/file3.json is corrupt from parquet's view
test_corrupt_df1 = spark.read.parquet("examples/src/main/resources/dir1/",
                                      "examples/src/main/resources/dir1/dir2/")
test_corrupt_df1.show()
# +-------------+
# |         file|
# +-------------+
# |file1.parquet|
# |file2.parquet|
# +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/python/sql/datasource.py”。
// enable ignore corrupt files via the data source option
// dir1/file3.json is corrupt from parquet's view
val testCorruptDF0 = spark.read.option("ignoreCorruptFiles", "true").parquet(
  "examples/src/main/resources/dir1/",
  "examples/src/main/resources/dir1/dir2/")
testCorruptDF0.show()
// +-------------+
// |         file|
// +-------------+
// |file1.parquet|
// |file2.parquet|
// +-------------+

// enable ignore corrupt files via the configuration
spark.sql("set spark.sql.files.ignoreCorruptFiles=true")
// dir1/file3.json is corrupt from parquet's view
val testCorruptDF1 = spark.read.parquet(
  "examples/src/main/resources/dir1/",
  "examples/src/main/resources/dir1/dir2/")
testCorruptDF1.show()
// +-------------+
// |         file|
// +-------------+
// |file1.parquet|
// |file2.parquet|
// +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/scala/org/apache/spark/examples/sql/SQLDataSourceExample.scala”。
// enable ignore corrupt files via the data source option
// dir1/file3.json is corrupt from parquet's view
Dataset<Row> testCorruptDF0 = spark.read().option("ignoreCorruptFiles", "true").parquet(
    "examples/src/main/resources/dir1/",
    "examples/src/main/resources/dir1/dir2/");
testCorruptDF0.show();
// +-------------+
// |         file|
// +-------------+
// |file1.parquet|
// |file2.parquet|
// +-------------+

// enable ignore corrupt files via the configuration
spark.sql("set spark.sql.files.ignoreCorruptFiles=true");
// dir1/file3.json is corrupt from parquet's view
Dataset<Row> testCorruptDF1 = spark.read().parquet(
        "examples/src/main/resources/dir1/",
        "examples/src/main/resources/dir1/dir2/");
testCorruptDF1.show();
// +-------------+
// |         file|
// +-------------+
// |file1.parquet|
// |file2.parquet|
// +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/java/org/apache/spark/examples/sql/JavaSQLDataSourceExample.java”。
# enable ignore corrupt files via the data source option
# dir1/file3.json is corrupt from parquet's view
testCorruptDF0 <- read.parquet(c("examples/src/main/resources/dir1/", "examples/src/main/resources/dir1/dir2/"), ignoreCorruptFiles = "true")
head(testCorruptDF0)
#            file
# 1 file1.parquet
# 2 file2.parquet

# enable ignore corrupt files via the configuration
sql("set spark.sql.files.ignoreCorruptFiles=true")
# dir1/file3.json is corrupt from parquet's view
testCorruptDF1 <- read.parquet(c("examples/src/main/resources/dir1/", "examples/src/main/resources/dir1/dir2/"))
head(testCorruptDF1)
#            file
# 1 file1.parquet
# 2 file2.parquet
在 Spark 仓库中找到完整的示例代码“examples/src/main/r/RSparkSQLExample.R”。

忽略丢失文件

Spark 允许您使用配置 spark.sql.files.ignoreMissingFiles 或数据源选项 ignoreMissingFiles 来忽略从文件中读取数据时遇到的丢失文件。这里,丢失文件实际上是指您构建 DataFrame 后目录下已删除的文件。当设置为 true 时,Spark 作业将在遇到丢失文件时继续运行,并且已读取的内容仍将被返回。

路径通配符过滤器

pathGlobFilter 用于仅包含文件名与模式匹配的文件。语法遵循 org.apache.hadoop.fs.GlobFilter。它不会改变分区发现的行为。

要加载路径与给定通配符模式匹配的文件,同时保持分区发现的行为,您可以使用

df = spark.read.load("examples/src/main/resources/dir1",
                     format="parquet", pathGlobFilter="*.parquet")
df.show()
# +-------------+
# |         file|
# +-------------+
# |file1.parquet|
# +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/python/sql/datasource.py”。
val testGlobFilterDF = spark.read.format("parquet")
  .option("pathGlobFilter", "*.parquet") // json file should be filtered out
  .load("examples/src/main/resources/dir1")
testGlobFilterDF.show()
// +-------------+
// |         file|
// +-------------+
// |file1.parquet|
// +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/scala/org/apache/spark/examples/sql/SQLDataSourceExample.scala”。
Dataset<Row> testGlobFilterDF = spark.read().format("parquet")
        .option("pathGlobFilter", "*.parquet") // json file should be filtered out
        .load("examples/src/main/resources/dir1");
testGlobFilterDF.show();
// +-------------+
// |         file|
// +-------------+
// |file1.parquet|
// +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/java/org/apache/spark/examples/sql/JavaSQLDataSourceExample.java”。
df <- read.df("examples/src/main/resources/dir1", "parquet", pathGlobFilter = "*.parquet")
#            file
# 1 file1.parquet
在 Spark 仓库中找到完整的示例代码“examples/src/main/r/RSparkSQLExample.R”。

递归文件查找

recursiveFileLookup 用于递归加载文件,它会禁用分区推断。它的默认值为 false。如果数据源在 recursiveFileLookup 为 true 时显式指定了 partitionSpec,则会抛出异常。

要递归加载所有文件,您可以使用

recursive_loaded_df = spark.read.format("parquet")\
    .option("recursiveFileLookup", "true")\
    .load("examples/src/main/resources/dir1")
recursive_loaded_df.show()
# +-------------+
# |         file|
# +-------------+
# |file1.parquet|
# |file2.parquet|
# +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/python/sql/datasource.py”。
val recursiveLoadedDF = spark.read.format("parquet")
  .option("recursiveFileLookup", "true")
  .load("examples/src/main/resources/dir1")
recursiveLoadedDF.show()
// +-------------+
// |         file|
// +-------------+
// |file1.parquet|
// |file2.parquet|
// +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/scala/org/apache/spark/examples/sql/SQLDataSourceExample.scala”。
Dataset<Row> recursiveLoadedDF = spark.read().format("parquet")
        .option("recursiveFileLookup", "true")
        .load("examples/src/main/resources/dir1");
recursiveLoadedDF.show();
// +-------------+
// |         file|
// +-------------+
// |file1.parquet|
// |file2.parquet|
// +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/java/org/apache/spark/examples/sql/JavaSQLDataSourceExample.java”。
recursiveLoadedDF <- read.df("examples/src/main/resources/dir1", "parquet", recursiveFileLookup = "true")
head(recursiveLoadedDF)
#            file
# 1 file1.parquet
# 2 file2.parquet
在 Spark 仓库中找到完整的示例代码“examples/src/main/r/RSparkSQLExample.R”。

修改时间路径过滤器

modifiedBeforemodifiedAfter 是可以一起或单独应用的选项,以便在 Spark 批处理查询期间加载哪些文件方面实现更高的粒度。(请注意,结构化流文件源不支持这些选项。)

当未提供时区选项时,时间戳将根据 Spark 会话时区 (spark.sql.session.timeZone) 进行解释。

要加载路径与给定修改时间范围匹配的文件,您可以使用

# Only load files modified before 07/1/2050 @ 08:30:00
df = spark.read.load("examples/src/main/resources/dir1",
                     format="parquet", modifiedBefore="2050-07-01T08:30:00")
df.show()
# +-------------+
# |         file|
# +-------------+
# |file1.parquet|
# +-------------+
# Only load files modified after 06/01/2050 @ 08:30:00
df = spark.read.load("examples/src/main/resources/dir1",
                     format="parquet", modifiedAfter="2050-06-01T08:30:00")
df.show()
# +-------------+
# |         file|
# +-------------+
# +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/python/sql/datasource.py”。
val beforeFilterDF = spark.read.format("parquet")
  // Files modified before 07/01/2020 at 05:30 are allowed
  .option("modifiedBefore", "2020-07-01T05:30:00")
  .load("examples/src/main/resources/dir1");
beforeFilterDF.show();
// +-------------+
// |         file|
// +-------------+
// |file1.parquet|
// +-------------+
val afterFilterDF = spark.read.format("parquet")
   // Files modified after 06/01/2020 at 05:30 are allowed
  .option("modifiedAfter", "2020-06-01T05:30:00")
  .load("examples/src/main/resources/dir1");
afterFilterDF.show();
// +-------------+
// |         file|
// +-------------+
// +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/scala/org/apache/spark/examples/sql/SQLDataSourceExample.scala”。
Dataset<Row> beforeFilterDF = spark.read().format("parquet")
        // Only load files modified before 7/1/2020 at 05:30
        .option("modifiedBefore", "2020-07-01T05:30:00")
        // Only load files modified after 6/1/2020 at 05:30
        .option("modifiedAfter", "2020-06-01T05:30:00")
        // Interpret both times above relative to CST timezone
        .option("timeZone", "CST")
        .load("examples/src/main/resources/dir1");
beforeFilterDF.show();
// +-------------+
// |         file|
// +-------------+
// |file1.parquet|
// +-------------+
在 Spark 仓库中找到完整的示例代码“examples/src/main/java/org/apache/spark/examples/sql/JavaSQLDataSourceExample.java”。
beforeDF <- read.df("examples/src/main/resources/dir1", "parquet", modifiedBefore= "2020-07-01T05:30:00")
#            file
# 1 file1.parquet
afterDF <- read.df("examples/src/main/resources/dir1", "parquet", modifiedAfter = "2020-06-01T05:30:00")
#            file
在 Spark 仓库中找到完整的示例代码“examples/src/main/r/RSparkSQLExample.R”。