讀寫 JSON 檔案

JSON(JavaScript 物件符號)是一種廣泛使用的半結構化資料交換與儲存格式。 Azure Databricks 支援 Apache Spark 的 JSON 讀寫,包括單行與多行模式、自動結構推論及救援資料。 你可以使用 Spark DataFrame API 或 SQL 從雲端儲存讀取 JSON 檔案,並將 DataFrame 寫回 JSON。

先決條件

Azure Databricks 使用 JSON 檔案不需要額外的設定。

選項

使用 .option() 和 .options() 的 DataFrameReader 和 DataFrameWriter 方法來配置 JSON 資料來源。 欲了解完整的支援選項清單,請參閱 DataFrameReader JSON 選項 與 DataFrameWriter JSON 選項。

Usage

以下範例使用 Wanderbricks 範例資料集,示範使用 Spark DataFrame API 與 SQL 在單行與多行模式下讀寫 JSON 檔案。

寫入與讀取 JSON 檔案

在單行模式(預設)中,輸出的每一行包含一個完整的 JSON 物件。 把 Wanderbricks 的評論寫成 JSON 格式,然後再回讀。

Python

# Write wanderbricks reviews to JSON format
df = spark.read.table("samples.wanderbricks.reviews")
df.write.format("json").save("/Volumes/<catalog>/<schema>/<volume>/reviews_json")

# Read the JSON files into a DataFrame
df = spark.read.format("json").load("/Volumes/<catalog>/<schema>/<volume>/reviews_json")
df.printSchema()
display(df)

程式語言 Scala

// Write wanderbricks reviews to JSON format
val reviews = spark.read.table("samples.wanderbricks.reviews")
reviews.write.format("json").save("/Volumes/<catalog>/<schema>/<volume>/reviews_json")

// Read the JSON files into a DataFrame
val df = spark.read.format("json").load("/Volumes/<catalog>/<schema>/<volume>/reviews_json")
df.printSchema()
df.show()

讀取多行 JSON 檔案

在多行模式下,單一 JSON 物件可以跨越多行。 啟用多行模式,以讀取跨多行格式化的 JSON 檔案。

Python

mdf = spark.read.option("multiline", "true").format("json").load("/Volumes/<catalog>/<schema>/<volume>/multi-line.json")
mdf.show(truncate=False)

程式語言 Scala

val mdf = spark.read.option("multiline", "true").format("json").load("/Volumes/<catalog>/<schema>/<volume>/multi-line.json")
mdf.show(false)

SQL

CREATE TEMPORARY VIEW multiLineJsonTable
USING json
OPTIONS (path="/Volumes/<catalog>/<schema>/<volume>/multi-line.json",multiline=true)

使用 SQL 讀取 JSON 檔案

你可以在 SQL 中使用 read_files 表值函式 來讀取 JSON 檔案。

SELECT * FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/reviews_json',
  format => 'json',
  multiLine => true)

你也可以使用 USING JSON 來讀取 JSON 檔案。 然而,Databricks 建議使用 read_files 代替 USING JSON,因為 read_files 允許規範結構及額外的檔案處理選項。

DROP TABLE IF EXISTS reviews_json_table;

CREATE TABLE reviews_json_table
USING JSON
OPTIONS (path "/Volumes/<catalog>/<schema>/<volume>/reviews_json", multiline true);

SELECT * FROM reviews_json_table;

指定字元編碼

根據預設,系統會自動偵測輸入檔的字元集。 您可以使用 charset 選項明確指定字元集:

Python

spark.read.option("charset", "UTF-16BE").format("json").load("/Volumes/<catalog>/<schema>/<volume>/fileInUTF16.json")

程式語言 Scala

spark.read.option("charset", "UTF-16BE").format("json").load("/Volumes/<catalog>/<schema>/<volume>/fileInUTF16.json")

SQL

SELECT * FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/fileInUTF16.json',
  format => 'json',
  charset => 'UTF-16BE'
)

某些支援的字元集包括:UTF-8、UTF-16BE、UTF-16LE、UTF-16、UTF-32BE、UTF-32LE、UTF-32。 如需 Oracle Java SE 所支援之字元集的完整清單,請參閱 支援的編碼。

啟用已救出的資料欄位

已救援資料欄位確保你在 ETL 期間不會遺失資料。 它會擷取任何未被解析的資料,因為記錄中的一個或多個欄位存在以下其中一種問題:

  • 從提供的架構中缺席。
  • 不符合所提供結構描述的資料類型。
  • 具有與所提供結構描述中欄位名稱不符的情況。

救援後的資料欄位會以 JSON blob 形式回傳,包含救援的欄位及記錄的來源檔案路徑。

要啟用已救援的資料欄位,讀取時請將選項設 rescuedDataColumn 為欄位名稱:

Python

df = spark.read.option("rescuedDataColumn", "_rescued_data").format("json").load("/Volumes/<catalog>/<schema>/<volume>/reviews_json")

程式語言 Scala

val df = spark.read.option("rescuedDataColumn", "_rescued_data").format("json").load("/Volumes/<catalog>/<schema>/<volume>/reviews_json")

SQL

SELECT * FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/reviews_json',
  format => 'json',
  rescuedDataColumn => '_rescued_data'
)

若要從已救援的資料欄位移除來源檔案路徑,請設定:

spark.conf.set("spark.databricks.sql.rescuedDataColumn.filePath.enabled", "false")

剖析記錄時,JSON 剖析器支援三種模式:PERMISSIVE、DROPMALFORMED 和 FAILFAST。 與 一起使用 rescuedDataColumn時,適用以下規則:

  • 資料型別不符不會在 DROPMALFORMED 模式下導致捨棄記錄,也不會在 FAILFAST 模式下引發錯誤。
  • 只有已損毀的記錄 (也就是不完整或格式錯誤的 JSON) 才會捨棄或擲回錯誤。
  • 如果你使用這個 badRecordsPath 選項,資料型別不符不會被視為壞紀錄。 只有不完整且格式錯誤的 JSON 記錄會儲存在 badRecordsPath 中。

其他資源

  • 讀寫 Parquet 檔案:如果你的工作負載主要是分析性且大量閱讀,Parquet 的欄式排版比 JSON 的列式文字格式提供更有效率的查詢效能。
  • 讀寫 Avro 檔案:如果你從像 Apache Kafka 這樣的事件串流系統產生或使用 JSON,Avro 提供更精簡的二進位編碼,並支援結構演化。