簡體   English   中英

直接使用來自 Databricks 的原始 SQL 查詢存儲在 Azure Data Lake 中的 avro 數據文件

[英]Querying avro data files stored in Azure Data Lake directly with raw SQL from Databricks

我正在使用 Databricks Notebooks 讀取存儲在 Azure Data Lake Gen2 中的 avro 文件。 avro 文件由事件中心捕獲創建,並呈現特定架構。 從這些文件中,我只需要提取 Body 字段,我感興趣的數據實際上存儲在該字段中。

我已經在 Python 中實現了這一點,它按預期工作:

path = 'abfss://file_system@storage_account.dfs.core.windows.net/root/YYYY/MM/DD/HH/mm/file.avro'
df0 = spark.read.format('avro').load(path) # 1
df1 = df0.select(df0.Body.cast('string')) # 2
rdd1 = df1.rdd.map(lambda x: x[0]) # 3
data = spark.read.json(rdd1) # 4

現在我需要將其轉換為原始 SQL 以便直接在 SQL 查詢中過濾數據。 考慮到上述4個步驟,SQL的步驟1和2如下:

CREATE TEMPORARY VIEW file_avro
USING avro
OPTIONS (path "abfss://file_system@storage_account.dfs.core.windows.net/root/YYYY/MM/DD/HH/mm/file.avro")

WITH body_array AS (SELECT cast(Body AS STRING) FROM file_avro)

SELECT * FROM body_array

通過這個部分查詢,我得到與上面的 df1 相同的結果(使用 Python 的第 2 步):

Body
[{"id":"a123","group":"0","value":1.0,"timestamp":"2020-01-01T00:00:00.0000000"},
{"id":"a123","group":"0","value":1.5,"timestamp":"2020-01-01T00:01:00.0000000"},
{"id":"a123","group":"0","value":2.3,"timestamp":"2020-01-01T00:02:00.0000000"},
{"id":"a123","group":"0","value":1.8,"timestamp":"2020-01-01T00:03:00.0000000"}]
[{"id":"b123","group":"0","value":2.0,"timestamp":"2020-01-01T00:00:01.0000000"},
{"id":"b123","group":"0","value":1.2,"timestamp":"2020-01-01T00:01:01.0000000"},
{"id":"b123","group":"0","value":2.1,"timestamp":"2020-01-01T00:02:01.0000000"},
{"id":"b123","group":"0","value":1.7,"timestamp":"2020-01-01T00:03:01.0000000"}]
...

我需要知道如何將步驟 3 和 4 引入 SQL 查詢中,將字符串解析為 json 對象,最后得到所需的 dataframe 和列。 謝謝。

我發現使用原始 SQL 執行此操作的一種方法如下,使用 from_json Spark SQL 內置 function 和 Body 字段的方案

CREATE TEMPORARY VIEW file_avro
USING avro
OPTIONS (path "abfss://file_system@storage_account.dfs.core.windows.net/root/YYYY/MM/DD/HH/mm/file.avro")

WITH body_array AS (SELECT cast(Body AS STRING) FROM file_avro),
data1 AS (SELECT from_json(Body, 'array<struct<id:string,group:string,value:double,timestamp:timestamp>>') FROM body_array),
data2 AS (SELECT explode(*) FROM data1),
data3 AS (SELECT col.* FROM data2)
SELECT * FROM data3 WHERE id = "a123"     --FILTERING BY CHANNEL ID

它的執行速度比我在問題中發布的 Python 代碼更快,這肯定是因為使用了 from_json 和 Body 的方案來提取其中的數據。 我在 PySpark 中的這種方法版本如下所示:

path = 'abfss://file_system@storage_account.dfs.core.windows.net/root/YYYY/MM/DD/HH/mm/file.avro'
df0 = spark.read.format('avro').load(path)
df1 = df0.selectExpr("cast(Body as string) as json_data")
df2 = df1.selectExpr("from_json(json_data, 'array<struct<id:string,group:string,value:double,timestamp:timestamp>>') as parsed_json")
data = df2.selectExpr("explode(parsed_json) as json").select("json.*")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM