Пользовательские источники, приёмники и преобразователи в задаче ETL

Блог Форсайт
Андрей Алифанов
Задача ETL позволяет работать со множеством источников, приемников и преобразователей. Здесь Excel, dBase, текстовые файлы с xml и разнообразные объекты репозитория. Но что делать, если нам нужно работать с данными в неподдерживаемых платформой форматах? Или преобразовывать данные каким-то специфическим образом? Здесь на помощь приходят пользовательские источники, приёмники и преобразователи. Для работы с ETL в целом не обязательно быть программистом – всю работу можно сделать через пользовательский интерфейс платформы. Но для работы с пользовательскими объектами необходимо иметь навыки программирования на Fore / Fore.NET.

Пользовательские источники

Давайте попробуем создать пользовательский источник. Мастер создания нового объекта задачи ETL представлен ниже: Если мы посмотрим на комментарий в верхней части окна, то увидим, что от нас требуется реализация одного из двух интерфейсов: IDtRecordsetProvider или IDtCustomProvider. Реализация интерфейса IDtRecordsetProvider – наиболее простой путь. Интерфейс содержит всего один метод, не принимающий никаких параметров и возвращающий двумерный массив. Но на этом достоинства такой реализации и заканчиваются. А вот недостатков здесь чуть менее, чем много. 🙂 Во-первых, код может быть написан только на Fore. Никакого Fore.NET. 🙁 Во-вторых, нет возможности управлять типами и именами полей в источнике данных. Имена полям назначаются ядром платформы (и имеют вид FIELD1, FIELD2, …), типы данных автоматически определяются ядром с помощью анализа содержимого первых нескольких записей источника. В-третьих, нет возможности управлять алгоритмом получения данных и управлять памятью – все данные возвращаются за один вызов, целым массивом. И т.д., и т.п. Ниже дана полная реализация IDtRecordsetProvider. Как можно увидеть – реализация действительно очень проста. В примере возвращается двумерный массив. В первом столбце массива возвращаются строки, во втором – вещественные числа. Если нас все эти ограничения не устраивают, мы должны использовать IDtCustomProvider. Этот способ гораздо сложнее в реализации, чем первый. Так как методов в интерфейсе гораздо больше. Зато при использовании данного интерфейса появляется возможность писать на Fore.NET (а значит, задействовать всю мощь платформы Microsoft.NET), задавать свои имена и типы данных полям, управлять процессом выдачи данных клиенту, потреблением памяти и т.д. Реализацию IDtCustomProvider я здесь приводить не буду – она занимает довольно много места. Минимальный код дан в тестовом репозитории (информация о том, как работать с тестовым репозиторием, в конце статьи).

Пользовательские приёмники

Итак, с источниками данных разобрались. Давайте посмотрим, что же нужно для реализации пользовательских приёмников. Как вы уже догадались, для них нужно написать реализацию интерфейсов IDtRecordsetConsumer или IDtCustomConsumer. 🙂 Достоинства и недостатки обеих реализаций приёмника аналогичны описанным ранее реализациям источника. Различается только набор методов в интерфейсах. Ниже дана реализация пользовательского приёмника. Как видите, она ненамного сложнее источника. Пример реализации IDtCustomConsumer занимает намного больше места и также есть в тестовом репозитории.

Пользовательские преобразователи

С источниками и приёмниками данных разобрались. Давайте теперь посмотрим, а как же реализовать свой механизм преобразования данных? Что для этого нужно? Давайте снова посмотрим на окно мастера: там есть подсказка. Подсказка говорит, что нужно указать некий макрос из некоего модуля. Давайте разберемся, что же это за макрос такой и как его написать? Сделать это мы можем тремя способами: 1. Написав статическую процедуру-член какого-либо класса (Shared в терминологии языков Fore/Fore.NET). 2. Написав глобальную процедуру (это справедливо только для Fore, так как в Fore.NET нет глобальных процедур). 3. Реализовав интерфейс IEtlCustomUser. В любом случае процедура должна принимать два параметра: входной и выходной наборы данных типа IEtlPlainRecordSets. В данном примере выбрана глобальная процедура UserTransform. Пример реализации своего преобразователя данных вы можете увидеть ниже. В примере преобразователь складывает данные в первых полях двух источников данных. Остальные поля первого источника передаются на выход без изменений, поля второго источника не задействуются. Чтобы не усложнять логику, в примере предполагается, что количество записей в обоих источниках одинаковое. В реальном примере, конечно, все будет не так просто. Так как преобразователь может иметь несколько входов и несколько выходов, появляется возможность разными способами комбинировать данные между источниками и приёмниками. Реальное применение ограничивается только фантазией разработчика и требованиями задачи. Итак, если собрать все наши реализованные объекты вместе, получится вот такая задача ETL. В задаче есть две одинаковых цепочки, с абсолютно одинаковыми источниками. А вот преобразователи и приёмники написаны по-разному, и даже на разных языках. Задача наглядно показывает, как можно достаточно просто реализовать объекты для работы с пользовательскими данными и алгоритмами.

Комментарии

Email не будет опубликован.
Подробнее о политике использования персональных данных