Выгрузка данных из SAP через RFC на Python

    Поговорим о выгрузке данных из SAP ERP или S/4 HANA с использованием механизма SAP RFC. 

    Такая выгрузка может служить для наполнения аналитического хранилища данных или для интеграции с другой системой.

    Интерфейс SAP RFC (remote function call) позволяет вызывать различные функции SAP из стороннего приложения.

    Преимущества этого интерфейса:

    • прямое и быстрое подключение с SAP.

    • возможность менять параметры запроса, запрашивая данные частями.

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

    Установка

    Для работы через RFC вам потребуется установить следующее:

    • Библиотека PyRFC https://github.com/SAP/PyRFC  pip install pynwrfc

    • Библиотека SAP NW RFC для вашей платформы, скачанный с https://support.sap.com (нужен акаунт SAP).

    • Установить переменную окружения, указав каталог с библиотекой SAP NW RFC:  SAPNWRFC_HOME=C:\NWRFC\nwrfcsdk\

    Поиск уже имеющихся в системе функций

    В системе SAP можно поискать уже готовые функциональные модули.

    Сделать это можно следующим образом:

    1. Запустить транзакцию SE16 (просмотр таблиц). 

    2. Указать имя таблицы TFDIR. 

    3. Задать фильтры для поиска:

    • FUNCNAME=*MATERIAL* (задать маску поиска)

    • FMODE=R (возможность вызова функции через механизм RFC)

    Чтение таблиц через RFC_READ_TABLE

    RFC_READ_TABLE позволяет выгружать данные из таблицы SAP, ограничивая выборку фильтрами.

    Несмотря на то, что SAP позиционирует эту функцию как тестовую и не предназначенную для использования в продуктивной среде, она вполне работоспособна.

    Следует сказать, что RFC_READ_TABLE часто неудобна, т.к. она позволяет читать только одну таблицу (не поддерживает JOIN).

    В этой статье я не буду подробно описывать работу с этой функцией, т.к. в интернете существует множество примеров ее использования. Вместо этого приведу пример вызова функции стандартной функции BAPI_MATERIAL_GETLIST, выдающий список материалов по заданным критериям поиска. 

    Просмотр функции через SE37

    Входные и выходные параметры функции можно просмотреть с использованием транзакции SE37.

    Параметры вызова функции присутствуют на следующих вкладках:

    • Importing - входные параметры простого типа (не табличные)

    • Exporting - выходные параметры простого типа

    • Tables - как входные, так и выходные параметры в виде таблиц

    Рассмотрим использование SE37 на примере BAPI_MATERIAL_GETLIST.

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

    SE37 - вкладка Tables
    SE37 - вкладка Tables
    Просмотр полей таблицы
    Просмотр полей таблицы

    Эта функция выдает не слишком много полезных данных: Номер материала и описание.

    Другие таблицы нужны для передачи  на вход параметров выборки.

    Например поиск по коду материала (MATNRSELECTION):

    Таблица входных значений
    Таблица входных значений

    Подключаемся к SAP

    Подключение к SAP с использованием библиотеки pyrfc делается не сложно. (Настройки подключения можно посмотреть в SAP GUI.)

    Код на Python:

    import pandas as pd

    import os

    import pyrfc

    conn = pyrfc.Connection(user='', passwd='', 

        mshost='111.111.11.11', msserv='3600', sysid='010',

        group='NN', saprouter='', lang='EN',client='')   

    Вызываем необходимую функцию

    Рассмотрим вызов функции на примере BAPI_MATERIAL_GETLIST.

    Сначала зададим входные параметры.

    В данном случае для каждого параметра в таблице будет по одной строке. 

    Строка таблицы задается как python dictionary, а вся таблица задается как list, состоящий из строк.

    В нашем примере укажем фильтр на код материала: '' (т.е. все значения), а также укажем значение для Plant.

    Для выборки используем SIGN="I" (Includes), 

    Варианты для OPTION:

    • EQ Equal

    • BT Between (требует задать значение для для LOW и HIGH)

    • LE Less Equal

    • GE Greater Equal

    • CP Contains Pattern

    matnrselection = [{'SIGN':'I', 'OPTION':'CP', 'MATNR_LOW':''}]

    plantselection = [{'SIGN':'I', 'OPTION':'EQ', 'PLANT_LOW':'NNNN'}]

    Далее вызываем функцию с этими параметрами.

    result = conn.call('BAPI_MATERIAL_GETLIST',

        MATNRSELECTION = matnrselection, PLANTSELECTION = plantselection)

    Преобразуем результат в DataFrame

    DataFrame можно получить в одну строку:

    df = pd.DataFrame(result['MATNRLIST'])

    Где MATNRLIST, это имя результирующей таблицы, указанное в разделе Tables.

    Итак, с помощью буквально нескольких строк кода, мы получили данные из SAP в DataFrame и можем дальше работать с этими данным используя все возможности языка Python.

    Комментарии 6

      0

      А с полномочиями что? Можно прямо любую таблицу прочесть? Вот безопасники-то обрадуются.

        0
        Добрый день! Когда вы подключаетесь к RFC, SAP проверяет полномочия вашего пользователя. Таблицы сможете прочитать те, которые разрешены правами. (Конечно лучше создать специальную учетную запись для интеграции).
        +1

        Как то сложновато. По моему проще сделать ICF сервис, который можно вызывать через rest и не использовать никаких библиотек.

          0
          Вопрос хороший. Могу себе вообразить сценарий, что данная задача интересна не той команде (1), которая саппортит сам ERP, а другой команде (2), которой нужны данные в своих целях. Поэтому (2) может хотеть уметь решать свои вопросы без привлечения команды (1). Например, потому что там сложные-коммуникации/индия-аутсорс/интернейшнл-шаблон/другое.
            0
            Наша ситуация отчасти похожа на описанную, хотя возможность ICF у нас тоже имеется. В системе уже есть довольно много хороших Z-интерфейсов, которые можно использовать, не привлекая разработчиков ABAP.
            Конечно, подключение RFC на начальной стадии потребует возни с библиотеками и параметрами коннекта, но это разовое действие.
            Если кто-то может высказаться на тему преимуществ/недостатков RFC/ICF, то было бы интересно узнать Ваши мнения.
              0
              Согласен с одной стороны. Помимо Z в стандарте есть уже куча сервисов, хотя они позволяют работать только со стандартными объектами.
              Когда то можно было вызывать ФМ по RFC через макросы в экселе, но сейчас в Win10 64 битной версии эти библиотеки не работают(
              Для меня самый оптимальный вариант это конечно же ICF, только вместо ФМ у тебя класс. И можно вызывать на любом языке и с любого места (если есть доступ к NW).
              Ну тут дело вкуса, и кто что знает)

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое