Мне нужно открыть и скопировать содержимое нескольких файлов XML, хранящихся в хранилище данных Azure, в базу данных SQL Azure.Это структура файла XML:
<?xml version="1.0" encoding="utf-8"?>
<FileSummary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="invoices.xsd">
<Header>
<SequenceNumber>1</SequenceNumber>
<Description>Hello</Description>
<ShipDate>20180101</ShipDate>
</Header>
<FileInvoices>
<InvoiceNumber>000000A</InvoiceNumber>
<InvoiceHeader>
<InvoiceHeaderDate>201800201</InvoiceHeaderDate>
<InvoiceHeaderDescription>XYZ</InvoiceHeaderDescription>
</InvoiceHeader>
<InvoiceItems>
<ItemId>000001</ItemId>
<ItemQuantity>000010</ItemQuantity>
<ItemPrice>000100</ItemPrice>
</InvoiceItems>
</FileInvoices>
<FileInvoices>
<InvoiceNumber>000000B</InvoiceNumber>
<InvoiceHeader>
<InvoiceHeaderDate>201800301</InvoiceHeaderDate>
<InvoiceHeaderDescription>ABC</InvoiceHeaderDescription>
</InvoiceHeader>
<InvoiceItems>
<ItemId>000002</ItemId>
<ItemQuantity>000020</ItemQuantity>
<ItemPrice>000200</ItemPrice>
</InvoiceItems>
</FileInvoices>
</FileSummary>
Поэтому я использовал блоки данных Azure для монтирования хранилища данных как "/ mnt / testdata", а затем попытался открыть файл примера выше с помощью следующей команды
dfXml = (sqlContext.read.format("xml") # requires maven library <HyukjinKwon:spark-xml:0.1.1-s_2.11>
.options(rootTag='FileSummary')
.load('/mnt/testdata/data/invoices_file1.xml'))
dfXml.cache()
print ("Number of records in this dataframe: " + str(dfXml.count()))
dfXml.printSchema()
возвращает следующий результат:
dfXml:pyspark.sql.dataframe.DataFrame
FileInvoices:array
element:struct
InvoiceHeader:struct
InvoiceHeaderDate:long
InvoiceHeaderDescription:string
InvoiceItems:struct
ItemId:long
ItemPrice:long
ItemQuantity:long
InvoiceNumber:string
Header:struct
Description:string
SequenceNumber:long
ShipDate:long
xmlns:xsi:string
xsi:noNamespaceSchemaLocation:string
Number of records in this dataframe: 1
root
|-- FileInvoices: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- InvoiceHeader: struct (nullable = true)
| | | |-- InvoiceHeaderDate: long (nullable = true)
| | | |-- InvoiceHeaderDescription: string (nullable = true)
| | |-- InvoiceItems: struct (nullable = true)
| | | |-- ItemId: long (nullable = true)
| | | |-- ItemPrice: long (nullable = true)
| | | |-- ItemQuantity: long (nullable = true)
| | |-- InvoiceNumber: string (nullable = true)
|-- Header: struct (nullable = true)
| |-- Description: string (nullable = true)
| |-- SequenceNumber: long (nullable = true)
| |-- ShipDate: long (nullable = true)
|-- xmlns:xsi: string (nullable = true)
|-- xsi:noNamespaceSchemaLocation: string (nullable = true)
Таким образом, похоже, что приведенная выше команда правильно читает файл и, конечно, я могу подключиться к моей хорошо нормализованной базе данных SQL Azure и записатьзаписи в конкретные таблицы:
dfXml.write.jdbc(url=jdbcUrl, table="dest_table", mode="overwrite", properties=connectionProperties)
, однако этот метод требует установки нескольких вложенных циклов и множества ручных задач для отслеживания ключей каждой таблицы и соблюдения ссылочной целостности, которые не используют архитектуру Spark, поэтому яТеперь мне интересно, есть ли лучшая практика (или готовая библиотека), которая делает эту задачу более автоматизированной и масштабируемой.
Я ожидаю, что это общая потребность, поэтому в идеале я бы использовал библиотеку, которая считывает полную структуру XML, показанную в начале, и автоматически извлекает информацию для вставки в нормализованные таблицы.
Большое спасибо за любое предложение.
Мауро