Делаем новых людей за 12 строк кода: как с Python ускорить подготовку демо-стенда по HR планированию и соблюсти закон

Привет, меня зовут Максим Бритвин, и я старший консультант-разработчик. Вот уже почти 10 лет я занимаюсь внедрением и доработкой проектов бюджетирования на платформе Oracle Hyperion, в частности интеграцией данных между Hyperion и различными источниками. Недавно мы с командой решили проверить возможность переноса существующих решений на базе Oracle Hyperion Planning на платформу «Форсайт», чтобы примерно понимать сложность, трудозатраты и сроки такого рода проектов. Второй задачей стало создание демо-стенда для бюджетирования HR ресурсов в максимально короткие сроки. Тут звезды сошлись идеально: у нас есть готовая реализация на Oracle Hyperion Planning, есть дедлайн, который как всегда близок, а значит пришло время делать проект.

Вводные на проект

На момент старта проекта у нас было:

  1. Исходная модель старого приложения для бюджетирования HR ресурсов на Oracle Hyperion Planning

  2. Набор фактических и плановых данных, которые необходимо загрузить и трансформировать в нужные аналитики

  3. Алгоритмы расчетов показателей для бюджетирования и оптимизации

  4. Установленная платформа «Форсайт. Бюджетирование» и только что сданный сертификат на разработчика в этой платформе.

Заметили главную проблему? У нас не было готового списка сотрудников для наполнения модели.

Да, был список номеров сотрудников, который использовался в старой версии приложений, но сейчас захотелось развить модель, добавить больше данных в систему, чтобы были видны не только цифры, но и люди.

А так как это задача по интеграции данных в приложение, то она автоматически стала моей.

Тестируем границы креатива — придумываем данные сами

Первая мысль была, что моего креатива хватит, чтобы самостоятельно придумать достаточное количество комбинаций имен, чтобы заполнить модель. Взять реально существующих сотрудников для демо-стенда мы не можем, ведь для этого нужно с каждого взять согласие на использование персональных данных. Попробовал придумать такие комбинации вручную — меня хватило на 50 различных комбинаций ФИО, паспортных данных и различных дополнительных показателей сотрудника и этого явно было мало для заполнения данных. В исходных данных у нас было около двух тысяч сотрудников, причем не у всех были заполнены нужные нам поля. Сроки поджимали, и пришло время призвать на помощь силу «ЯжАйтишник» и поискать способ, как сгенерировать нужный нам объем данных автоматически.

В поисках готового решения я нашел библиотеку для Python — Mimesis. Она предоставляет достаточно простое решение для генерации всех нужных данных, работает с российскими стандартами и может создать все нужные валидные данные для загрузки. Кроме того, я очень хотел посмотреть на поддержку Python в Форсайт, так что пришло время написать немного кода.

P.S. Во время написания этой статьи я нашел похожую библиотеку для генерации — Faker . У нее побольше доступных методов для генерации дополнительных данных, например, имен банков, номеров машин и многих других. Если вам потребуется создавать такие поля — можно посмотреть на нее.

Как сделать человека за пару строчек кода

Сперва попробуем разобраться как работает выбранная библиотека — обратимся в документацию в секцию QuickStart и адаптируем ее под наши нужды. Код для генерации данных сотрудника выглядит так:

aed50a4f1a22c4d01c475a252f023de3.png

На строках 1–4 импортируем все, что нам нужно из библиотеки. На строках 9–10 создаем объект поставщика данных (DataProvider) с указанием конкретного языка и добавляем к нему еще один — конкретно для особенностей нашей страны. В Generic поставщике данных у нас есть базовый набор полей — «Имя», «Фамилия» и другие общие для многих стран поля. В RussiaSpecProvider есть уже те поля, которых нет у других стран, например «Отчество».

Далее по коду, генерируем случайно пол для нашего сотрудника и на основе этих данных уже создаем нужные нам атрибуты и выводим на экран. Супер, одного сотрудника мы создавать научились. Как быть, если нам нужно больше сотрудников? И так как мы планируем загружать этот набор данных автоматически, с помощью ETL инструмента, то он должен быть еще и структурирован. Тут на помощь приходит такой класс, как Schema.

В общих чертах, что нам дает использование схемы:

  1. Мы определяем все нужные поля в одном месте, потом вызываем create и у нас создается вся нужная информация.

  2. При создании схемы мы можем дополнительно указать количество итераций создания, то есть не нужно это напрямую делать в цикле, библиотека все делает за нас.

В итоге получается вот такой код для генерации данных:

df7baf626fa4774d9f6a67b62b20b5e5.png

На этом шаге у нас есть готовый Python скрипт, который создаст нам столько сотрудников, сколько мы захотим. Теперь пойдем узнаем, как его применить в Форсайт.

Структура решения

Так как мы хотим иметь повторяемый процесс, который можно было бы использовать неоднократно, то появилась следующая структура:

  1. Есть исходный файл в формате csv, в котором нужно заменить персональные данные сотрудников и оставить остальные атрибуты неизменными

  2. В Форсайте создали справочник НСИ, куда добавили уже все необходимые поля

Для загрузки данных будем использовать встроенный ETL инструмент, который позволит нам открыть исходный файл, обработать его с помощью Python и загрузить данные в справочник.

Весь процесс в задаче ETL:

32e0f43e10eaa5ebd842d67862f6ab43.png

Применяем Python в Форсайт

На момент написания статьи мы не можем просто вызвать Python модуль, всю конструкцию необходимо обернуть в модуль, написанный на языке Fore.

Из документации я выделил 2 способа вызова Python кода, зависящих от того, где вы будете хранить ваши Python модули:

  1. Python.Invoke (ModuleName: String; FunctionName: String; Params: Array): Variant; — данный способ используется, когда мы не хотим хранить наши Python модули в репозитории платформы. Возможно, данные методы будут полезны для каких-то технических расчетов или обработок, которые не должны быть видны. При этом, есть ряд определенных мест, где будет выполняться поиск модуля, указанного при вызове функции:

  2. Python.InvokeModule (ModuleId: String, FunctionName: String, Params: Array): Variant; — Если мы храним наш Python модуль в репозитории решения — можем использовать такой вариант. В этом случае в первом параметре передаем Id объекта.

Итого у нас есть 3 объекта, которые нам нужны для решения задачи:

2464eecae943eb839c4016676c1e4691.png

Сама ETL процедура, модуль Fore, который используем для обработки значений из ETL процедуры и Python модуль, который нам генерирует нужные значения.

Теперь нужно это все объединить в одно целое и загрузить в справочник.

Модуль Fore — это модуль преобразования данных по алгоритму пользователя. У него есть своя определенная структура, по которой платформа определяет — какие методы нужно запускать во время загрузки и обработки данных.

Для использования этого модуля в ETL нужно реализовать один класс, который будет наследоваться от интерфейса IEtlCustomUser и реализовать внутри 2 метода Read и Transform.

44c287e84052535def23b657d78b6d0c.png

В нашем случае нам нужен только метод Transform, поэтому кратко пройдемся по нему:

На вход к нам попадает 2 объекта — список источников и список выходных данных. Поля, которые есть в этих объектах, настраиваются в самой процедуре ETL. Далее мы получаем количество входящих записей и передаем его, как аргумент функции в Python.

0636d839b7812c5fee61bf1cd71e80a0.png

После выполнения функции из Python в переменной persons_FIO у нас находится список словарей с нужными нам полями. Запускаем цикл по каждой записи в источнике и заменяем необходимые нам поля по ключу. Например, получаем поле full_name из нашего списка словарей

fedf6f9abc9554c16bda1d522d29dbe7.png

И далее, в конце цикла добавляем новую запись в выходные данные и заполняем их по ключам:

ddf25958ee569a36b66a296d143df2ae.png

После окончания загрузки мы получим необходимый нам набор сотрудников, еще и с очень необычными именами, например Бруштейн Галактион Юльевич.

Итоги решения

Главный итог — мы смогли наполнить наше решение нормальными данными, при этом не раскрывая ни одной персональной информации. Большим плюсом было то, что времени на разработку такого решения было затрачено минимальное количество — со всеми исследованиями и попытками ушел рабочий день. Так что скорость ведения разработки на платформе приятно удивляет.

Кроме того, здесь мы используем Python 3.11 — на момент написания это актуальная версия Python, соответственно много чего мы можем использовать в своем коде. Применение не ограничивается только ETL процедурами, мы также можем использовать модули Python в расчетах, можем подключаться к нашему репозиторию напрямую и выполнять технические операции по созданию справочников и т.д.

Кроме того, использование Python актуальной версии позволяет использовать любые существующие библиотеки для анализа или статистики, такие как NumPy, Pandas и другие, что будет полезно при выполнении сложных расчетов.

Если Python — не ваш язык, то можно посмотреть в сторону альтернатив, ведь платформа предоставляет библиотеки для Java или C#.

Данная особенность Форсайта позволяет реализовать даже самые смелые проекты и запросы пользователей, которые на других платформах не могли бы быть реализованы в силу ограничений одного языка разработки.

© Habrahabr.ru