Как Greenplum хранит и обрабатывает XML-документы, зачем для этого нужны утилиты gpfdist и gpload, каковы их конфигурации для выполнения XSLT-преобразований XML-файлов и их загрузки/выборки во внешние таблицы MPP-СУБД.
Работа с XML-документами и XSLT-преобразования в Greenplum
Greenplum, как и PostgreSQL, также поддерживает работу со сложными типами данных и может вести себя подобно документо-ориентированной СУБД, обрабатывая не только JSON, но и XML-документы. Для этого есть специальный тип данных – xml, который проверяет правильность входных значений XML-документа, а также позволяет выполнять над этими данными типобезопасные операции. Для использования этого типа данных конфигурация развертывания с библиотекой libxml, что включено по умолчанию для сборок VMware Greenplum.
Тип данных xml хранит правильно сформированные XML-документы, как определено стандартом XML, а также фрагменты содержимого, которые определяются путем ссылки на более разрешительный узел документа модели XQuery и XPath. Это означает, что фрагменты контента могут иметь более одного элемента верхнего уровня или символьного узла. Выражение IS DOCUMENT позволяет оценить, является ли конкретное xml-значение полным документом или только фрагментом содержимого.
Чтобы избежать ошибок из-за разной кодировки XML-документов на клиенте и на сервере, рекомендуется делать их одинаковыми. Поскольку XML-данные в Greenplum обрабатываются в UTF-8, вычисления будут наиболее эффективными, если кодировка сервера также будет UTF-8.
Тип данных xml не содержит операторов сравнения, поскольку не существует четко определенного и универсально полезного алгоритма сравнения данных XML. Поэтому невозможно получить строки таблицы простым сравнением столбца со значением поиска в XML-документе. Хотя значения XML обычно имеют отдельное ключевое поле, например, идентификатор, можно сперва преобразовать значения XML в символьные строки. Из-за отсутствия в этом типе данных операторов сравнения, создать индекс для столбца этого типа тоже нельзя. Поэтому для быстрого поиска в XML-данных можно привести выражение к типу символьной строки и индексировать его или индексировать выражение XPath. Фактический запрос придется корректировать для поиска по индексированному выражению.
Greenplum может читать и записывать XML-данные во внешние таблицы и из них с помощью утилиты gpfdist, которая работает с форматами данных, не поддерживаемых инструкцией CREATE EXTERNAL TABLE. Преобразование ввода считывает файл в формате внешних данных и выводит строки в формате, указанном в предложении внешней таблицы FORMAT. Выходное преобразование получает строки в текстовом формате и преобразует их в формат внешних данных gpfdist. Чтобы настроить это преобразование формата данных, надо выполнить команду, которую утилита gpfdist может вызываться с именем файла, содержащего XML-данные. Например, написать скрипт, который выполняет XSLT-преобразование XML-файла для вывода строк, чьи столбцы разделены вертикальной чертой |.
Преобразования настраиваются в файле конфигурации в формате YAML, который передается утилите gpfdist в командной строке. Если надо загрузить внешние данные в таблицу Greenplum, можно использовать утилиту gpload для автоматизации задач по созданию внешней таблицы, запуску gpfdist и загрузке преобразованных данных в таблицу базы данных.
Наиболее распространенным сценарием XSLT-преобразований XML-файлов в Greenplum является доступ к данным во внешних XML-файлах. Утилита gpfdist выполняет преобразование файлов XML на ETL-сервере следующим образом:
- определяет схему XSLT-преобразования;
- выполняет XSLT-преобразование согласно настройкам в файле конфигурации gpfdist
- переносит данные в таблицу Greenplum.
Напомним, XSLT (eXtensible Stylesheet Language Transformations) — язык преобразования XML-документов. XSLT позволяет отделить данные от их представления и преобразовать XML-документы из одной XSD-схемы в другую. Правила преобразования данных из исходного дерева XML-документа пишутся на языке запросов XPath. XSLT-процессор получает на входе два документа: входной XML-документ и таблицу стилей XSLT, чтобы создать выходной документ.
Язык XSLT является декларативным: он определяет правила, которые будут применяться к XML-документу во время преобразования по фиксированному алгоритму. Сначала XSLT-процессор разбирает файл преобразования и строит XML-дерево входного файла, затем ищет подходящий для корневого узла шаблон и вычисляет его содержимое. Инструкции в каждом шаблоне декларируют XSLT-процессору создание определенного тега или обработку какого-либо узла по какому-то правилу. Как это сделать, рассмотрим далее на примере.
Практический пример
В качестве практического примера возьмем исходный XML-документ, который содержит набор данных по заявкам слушателей на курсы по бизнес-анализу:
<?xml version="1.0" encoding="UTF-8"?> <apps xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:appsItem> <wishes> <info>Позвоните мне для уточнения деталей</info> <group >false</group > <online>false</online> <city>Москва</city> <country>Россия</country> </wishes> <corp>false</corp> <phone>998887766</phone> <name>Алексей</name> <course>MODP</course> </xs:appsItem> <xs:appsItem> <wishes> <company>Банк</company> <group >true</group > <online>false</online> <city>Астана</city> <country>Казахстан</country> </wishes> <corp>true</corp> <email>nikita@email.bank</email> <phone>1122334455</phone> <name>Никита</name> <course>BAMP</course> </xs:appsItem> <xs:appsItem> <wishes> <info>Прошу связаться со мной в телеграм</info> <group >true</group > <online>true</online> <country>Россия</country> </wishes> <corp>false</corp> <phone>987654321</phone> <name>Лиза</name> <course>OAIS</course> </xs:appsItem> <xs:appsItem> <wishes> <group >false</group > <online>true</online> </wishes> <corp>false</corp> <email>boris@email.ru</email> <name>Борис</name> <course>MODP</course> </xs:appsItem> <xs:appsItem> <wishes> <number_of_students>20</number_of_students> <group >true</group > <online>true</online> <city>Казань</city> </wishes> <corp>true</corp> <phone>123456789</phone> <email>anna@email.ru</email> <name>Анна</name> <course>TTIS</course> </xs:appsItem> </apps>
Предположим, необходимо преобразовать эти данные в текстовый формат с разделителями в несколько столбцов: course, name, phone, email, corp, wishes. XSLT-спецификация, которая будет описывать это преобразование, выглядит так:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsl:output method="text" encoding="ISO-8859-1"/> <!-- Шаблон для корневого элемента --> <xsl:template match="/apps"> <!-- Заголовок таблицы --> <xsl:text>course, name, phone, email, corp, wishes </xsl:text> <!-- Применить шаблоны ко всем элементам appsItem --> <xsl:apply-templates select="xs:appsItem"/> </xsl:template> <!-- Шаблон для элемента appsItem --> <xsl:template match="xs:appsItem"> <!-- Извлечение и вывод значений элементов --> <xsl:value-of select="course"/><xsl:text> | </xsl:text> <xsl:value-of select="name"/><xsl:text> | </xsl:text> <xsl:value-of select="phone"/><xsl:text> | </xsl:text> <xsl:value-of select="email"/><xsl:text> | </xsl:text> <xsl:value-of select="corp"/><xsl:text> | </xsl:text> <!-- Обработка элемента wishes --> <xsl:apply-templates select="wishes"/> <!-- Добавление перевода строки после каждой записи --> <xsl:if test="position()!=last()"><xsl:text> </xsl:text></xsl:if> </xsl:template> <!-- Шаблон для элемента wishes --> <xsl:template match="wishes"> <!-- Вывод информации из элемента wishes в виде текста --> <xsl:text>"</xsl:text> <!-- Начало --> <xsl:apply-templates select="info | company | number_of_students | group | online | city | country"/> <xsl:text>"</xsl:text> <!-- Конец --> </xsl:template> <!-- Шаблон для элементов внутри wishes --> <xsl:template match="wishes/*"> <!-- Вывод текста каждого элемента, за исключением последнего --> <xsl:value-of select="."/> <xsl:if test="position()!=last()"><xsl:text>, </xsl:text></xsl:if> </xsl:template> </xsl:stylesheet>
Этот XSLT-шаблон преобразует исходный XML в текстовый формат с разделителями. Для полей email и wishes, которые могут отсутствовать, преобразование может выводить пустую строку. Также, информация из wishes объединяется в одно поле, окружённое кавычками.
Целью этого преобразования является импорт всех данных во внешнюю таблицу Greenplum назавнием applications_table с текстовыми полями course, name, phone, email, corp, wishes. Для этого нужно запустить утилиту gpfdist с настроенным файлом конфигурации, создать внешнюю таблицу и загрузить туда данные, а потом остановить gpfdist. XLST-преобразование указывается в предложении CREATE EXTERNAL TABLE определения LOCATION:
CREATE EXTERNAL TABLE applications_table ( course TEXT, name TEXT, phone TEXT, email TEXT, corp TEXT, wishes TEXT ) LOCATION ('gpfdist://file_location/filename.txt') -- путь к файлу FORMAT 'TEXT' (DELIMITER '|' NULL '') --указан разделитель LOG ERRORS INTO err_table_name SEGMENT REJECT LIMIT 100 ROWS; -- логирование ошибок
Файл конфигурации gpfdist использует YAML-формат версии 1.1 и реализует схему для определения параметров преобразования. Утилита gpfdist обрабатывает документ по порядку и использует отступы (пробелы) для определения иерархии документа и взаимоотношений разделов друг с другом. Базовая структура файла конфигурации для рассматриваемого примера выглядит так:
--- VERSION: 1.0.0.1 TRANSFORMATIONS: application_input: TYPE: input COMMAND: /bin/bash/ CONTENT: data SAFE: posix-regex STDERR: server | console COMMAND: command ...
Можно автоматизировать процесс переноса данных с помощью утилиты gpload, которая создает внешнюю таблицу в Greenplum, запустит экземпляры gpfdist с файлом конфигурации, содержащим преобразование и выполнит команду вставки INSERT INTO или выборки данных SELECT FROM, а также удалит определение внешней таблицы. Для этого необходимо задать настройки преобразования TRANSFORM и TRANSFORM_CONFIG в разделе INPUT управляющего файла утилиты gpload. Параметр TRANSFORM_CONFIG указывает имя файла конфигурации gpfdist, а TRANSFORM указывает имя преобразования, описанного в файле с именем TRANSFORM_CONFIG.
--- VERSION: 1.0.0.1 DATABASE: ops USER: gpadmin GPLOAD: INPUT: - TRANSFORM_CONFIG: config.yaml - TRANSFORM: application_input - SOURCE: FILE: application.xml
Имя преобразования должно появиться в двух местах: в настройке TRANSFORM файла конфигурации gpfdist и в разделе TRANSFORMATIONS файла, указанного в TRANSFORM_CONFIG. В управляющем файле gpload можно задать необязательный параметр MAX_LINE_LENGTH, который указывает максимальную длину строки в данных преобразования XML, передаваемых в gpload.
После загрузки данных из XML-документов во внешние таблицы Greenplum, к ним можно обращаться с помощью стандартных SQL-операторов, которые поддерживает эта MPP-СУБД.
Узнайте больше про администрирование и эксплуатацию Greenplum для аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники