簡體   English   中英

用於激發 StructType 的 Avro Schema

[英]Avro Schema to spark StructType

這實際上與我之前的問題相同,但使用 Avro 而不是 JSON 作為數據格式。

我正在使用 Spark dataframe,它可以從幾個不同的模式版本之一加載數據:

// Version One
{"namespace": "com.example.avro",
 "type": "record",
 "name": "MeObject",
 "fields": [
     {"name": "A", "type": ["null", "int"], "default": null}
 ]
}

// Version Two
{"namespace": "com.example.avro",
 "type": "record",
 "name": "MeObject",
 "fields": [
     {"name": "A", "type": ["null", "int"], "default": null},
     {"name": "B", "type": ["null", "int"], "default": null}
 ]
}

我正在使用Spark Avro加載數據。

DataFrame df = context.read()
  .format("com.databricks.spark.avro")
  .load("path/to/avro/file");

這可能是版本一文件或版本二文件。 但是我希望能夠以相同的方式處理它,將未知值設置為“null”。 我在上一個問題中的建議是設置模式,但是我不想重復自己在.avro文件中編寫模式,並作為 sparks StructType和朋友。 如何將 avro 模式(文本文件或生成的MeObject.getClassSchema() )轉換為 sparks StructType

Spark Avro 有一個SchemaConverters ,但它是私有的並返回一些奇怪的內部 object。

免責聲明 :這是一種骯臟的黑客行為。 這取決於一些事情:

  • Python提供了一個輕量級的Avro處理庫 ,由於它的動態性,它不需要類型化的編寫器
  • 空的Avro文件仍然是有效的文檔
  • Spark模式可以轉換為JSON和從JSON轉換

以下代碼讀取Avro架構文件,使用給定架構創建空Avro文件,使用spark-csv讀取它並將Spark架構輸出為JSON文件。

import argparse
import tempfile

import avro.schema
from avro.datafile import DataFileWriter
from avro.io import DatumWriter

from pyspark import SparkContext
from pyspark.sql import SQLContext

def parse_schema(schema):
    with open(schema) as fr:
        return avro.schema.parse(open(schema).read())

def write_dummy(schema):
    tmp = tempfile.mktemp(suffix='.avro')
    with open(tmp, "w") as fw:
        writer = DataFileWriter(fw, DatumWriter(), schema)
        writer.close()
    return tmp

def write_spark_schema(path, schema):
    with open(path, 'w') as fw:
        fw.write(schema.json())


def main():
    parser = argparse.ArgumentParser(description='Avro schema converter')
    parser.add_argument('--schema')
    parser.add_argument('--output')
    args = parser.parse_args()

    sc = SparkContext('local[1]', 'Avro schema converter')
    sqlContext = SQLContext(sc)

    df = (sqlContext.read.format('com.databricks.spark.avro')
            .load(write_dummy(parse_schema(args.schema))))

    write_spark_schema(args.output, df.schema)
    sc.stop()


if __name__ == '__main__':
    main()

用法:

bin/spark-submit --packages com.databricks:spark-avro_2.10:2.0.1 \ 
   avro_to_spark_schema.py \
   --schema path_to_avro_schema.avsc \
   --output path_to_spark_schema.json

讀取架構:

import scala.io.Source
import org.apache.spark.sql.types.{DataType, StructType}

val json: String = Source.fromFile("schema.json").getLines.toList.head
val schema: StructType = DataType.fromJson(json).asInstanceOf[StructType]

請看看這是否有幫助,雖然不是很晚。 我正在為現在的工作努力。 我使用過Databricks的schemaconverter。 我想,你試圖用給定的模式讀取avro文件。

 val schemaObj = new Schema.Parser().parse(new File(avscfilepath));
 var sparkSchema : StructType = new StructType
 import scala.collection.JavaConversions._     
 for(field <- schemaObj.getFields()){
  sparkSchema = sparkSchema.add(field.name, SchemaConverters.toSqlType(field.schema).dataType)
 }
 sparkSchema

使用 PySpark:

with open('path/to/avro/file','r') as avro_file:
        avro_scheme = avro_file.read()
    
    df = spark\
        .read\
        .format("avro")\
        .option("avroSchema", avro_scheme)\
        .load()
    
    df.schema

暫無
暫無

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

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