Делаем новых людей за 12 строк кода: как с Python ускорить подготовку демо-стенда по HR планированию и соблюсти закон
Привет, меня зовут Максим Бритвин, и я старший консультант-разработчик. Вот уже почти 10 лет я занимаюсь внедрением и доработкой проектов бюджетирования на платформе Oracle Hyperion, в частности интеграцией данных между Hyperion и различными источниками. Недавно мы с командой решили проверить возможность переноса существующих решений на базе Oracle Hyperion Planning на платформу «Форсайт», чтобы примерно понимать сложность, трудозатраты и сроки такого рода проектов. Второй задачей стало создание демо-стенда для бюджетирования HR ресурсов в максимально короткие сроки. Тут звезды сошлись идеально: у нас есть готовая реализация на Oracle Hyperion Planning, есть дедлайн, который как всегда близок, а значит пришло время делать проект.
Вводные на проект
На момент старта проекта у нас было:
Исходная модель старого приложения для бюджетирования HR ресурсов на Oracle Hyperion Planning
Набор фактических и плановых данных, которые необходимо загрузить и трансформировать в нужные аналитики
Алгоритмы расчетов показателей для бюджетирования и оптимизации
Установленная платформа «Форсайт. Бюджетирование» и только что сданный сертификат на разработчика в этой платформе.
Заметили главную проблему? У нас не было готового списка сотрудников для наполнения модели.
Да, был список номеров сотрудников, который использовался в старой версии приложений, но сейчас захотелось развить модель, добавить больше данных в систему, чтобы были видны не только цифры, но и люди.
А так как это задача по интеграции данных в приложение, то она автоматически стала моей.
Тестируем границы креатива — придумываем данные сами
Первая мысль была, что моего креатива хватит, чтобы самостоятельно придумать достаточное количество комбинаций имен, чтобы заполнить модель. Взять реально существующих сотрудников для демо-стенда мы не можем, ведь для этого нужно с каждого взять согласие на использование персональных данных. Попробовал придумать такие комбинации вручную — меня хватило на 50 различных комбинаций ФИО, паспортных данных и различных дополнительных показателей сотрудника и этого явно было мало для заполнения данных. В исходных данных у нас было около двух тысяч сотрудников, причем не у всех были заполнены нужные нам поля. Сроки поджимали, и пришло время призвать на помощь силу «ЯжАйтишник» и поискать способ, как сгенерировать нужный нам объем данных автоматически.
В поисках готового решения я нашел библиотеку для Python — Mimesis. Она предоставляет достаточно простое решение для генерации всех нужных данных, работает с российскими стандартами и может создать все нужные валидные данные для загрузки. Кроме того, я очень хотел посмотреть на поддержку Python в Форсайт, так что пришло время написать немного кода.
P.S. Во время написания этой статьи я нашел похожую библиотеку для генерации — Faker . У нее побольше доступных методов для генерации дополнительных данных, например, имен банков, номеров машин и многих других. Если вам потребуется создавать такие поля — можно посмотреть на нее.
Как сделать человека за пару строчек кода
Сперва попробуем разобраться как работает выбранная библиотека — обратимся в документацию в секцию QuickStart и адаптируем ее под наши нужды. Код для генерации данных сотрудника выглядит так:
На строках 1–4 импортируем все, что нам нужно из библиотеки. На строках 9–10 создаем объект поставщика данных (DataProvider) с указанием конкретного языка и добавляем к нему еще один — конкретно для особенностей нашей страны. В Generic поставщике данных у нас есть базовый набор полей — «Имя», «Фамилия» и другие общие для многих стран поля. В RussiaSpecProvider есть уже те поля, которых нет у других стран, например «Отчество».
Далее по коду, генерируем случайно пол для нашего сотрудника и на основе этих данных уже создаем нужные нам атрибуты и выводим на экран. Супер, одного сотрудника мы создавать научились. Как быть, если нам нужно больше сотрудников? И так как мы планируем загружать этот набор данных автоматически, с помощью ETL инструмента, то он должен быть еще и структурирован. Тут на помощь приходит такой класс, как Schema.
В общих чертах, что нам дает использование схемы:
Мы определяем все нужные поля в одном месте, потом вызываем create и у нас создается вся нужная информация.
При создании схемы мы можем дополнительно указать количество итераций создания, то есть не нужно это напрямую делать в цикле, библиотека все делает за нас.
В итоге получается вот такой код для генерации данных:
На этом шаге у нас есть готовый Python скрипт, который создаст нам столько сотрудников, сколько мы захотим. Теперь пойдем узнаем, как его применить в Форсайт.
Структура решения
Так как мы хотим иметь повторяемый процесс, который можно было бы использовать неоднократно, то появилась следующая структура:
Есть исходный файл в формате csv, в котором нужно заменить персональные данные сотрудников и оставить остальные атрибуты неизменными
В Форсайте создали справочник НСИ, куда добавили уже все необходимые поля
Для загрузки данных будем использовать встроенный ETL инструмент, который позволит нам открыть исходный файл, обработать его с помощью Python и загрузить данные в справочник.
Весь процесс в задаче ETL:
Применяем Python в Форсайт
На момент написания статьи мы не можем просто вызвать Python модуль, всю конструкцию необходимо обернуть в модуль, написанный на языке Fore.
Из документации я выделил 2 способа вызова Python кода, зависящих от того, где вы будете хранить ваши Python модули:
Python.Invoke (ModuleName: String; FunctionName: String; Params: Array): Variant; — данный способ используется, когда мы не хотим хранить наши Python модули в репозитории платформы. Возможно, данные методы будут полезны для каких-то технических расчетов или обработок, которые не должны быть видны. При этом, есть ряд определенных мест, где будет выполняться поиск модуля, указанного при вызове функции:
Python.InvokeModule (ModuleId: String, FunctionName: String, Params: Array): Variant; — Если мы храним наш Python модуль в репозитории решения — можем использовать такой вариант. В этом случае в первом параметре передаем Id объекта.
Итого у нас есть 3 объекта, которые нам нужны для решения задачи:
Сама ETL процедура, модуль Fore, который используем для обработки значений из ETL процедуры и Python модуль, который нам генерирует нужные значения.
Теперь нужно это все объединить в одно целое и загрузить в справочник.
Модуль Fore — это модуль преобразования данных по алгоритму пользователя. У него есть своя определенная структура, по которой платформа определяет — какие методы нужно запускать во время загрузки и обработки данных.
Для использования этого модуля в ETL нужно реализовать один класс, который будет наследоваться от интерфейса IEtlCustomUser и реализовать внутри 2 метода Read и Transform.
В нашем случае нам нужен только метод Transform, поэтому кратко пройдемся по нему:
На вход к нам попадает 2 объекта — список источников и список выходных данных. Поля, которые есть в этих объектах, настраиваются в самой процедуре ETL. Далее мы получаем количество входящих записей и передаем его, как аргумент функции в Python.
После выполнения функции из Python в переменной persons_FIO у нас находится список словарей с нужными нам полями. Запускаем цикл по каждой записи в источнике и заменяем необходимые нам поля по ключу. Например, получаем поле full_name из нашего списка словарей
И далее, в конце цикла добавляем новую запись в выходные данные и заполняем их по ключам:
После окончания загрузки мы получим необходимый нам набор сотрудников, еще и с очень необычными именами, например Бруштейн Галактион Юльевич.
Итоги решения
Главный итог — мы смогли наполнить наше решение нормальными данными, при этом не раскрывая ни одной персональной информации. Большим плюсом было то, что времени на разработку такого решения было затрачено минимальное количество — со всеми исследованиями и попытками ушел рабочий день. Так что скорость ведения разработки на платформе приятно удивляет.
Кроме того, здесь мы используем Python 3.11 — на момент написания это актуальная версия Python, соответственно много чего мы можем использовать в своем коде. Применение не ограничивается только ETL процедурами, мы также можем использовать модули Python в расчетах, можем подключаться к нашему репозиторию напрямую и выполнять технические операции по созданию справочников и т.д.
Кроме того, использование Python актуальной версии позволяет использовать любые существующие библиотеки для анализа или статистики, такие как NumPy, Pandas и другие, что будет полезно при выполнении сложных расчетов.
Если Python — не ваш язык, то можно посмотреть в сторону альтернатив, ведь платформа предоставляет библиотеки для Java или C#.
Данная особенность Форсайта позволяет реализовать даже самые смелые проекты и запросы пользователей, которые на других платформах не могли бы быть реализованы в силу ограничений одного языка разработки.