[Из песочницы] SAP и Python интеграция или как забрать данные из SAP проще
Добрый день, Хабр!
Хочу поделится опытом интересной задачи по тому как без труда взаимодействовать с системами SAP с помощью Python — не важно какой модуль или версия платформы.
Если интересно только техническое решение, то пропускайте всю лирику и смотрите пример реализации.
Лирика
Все свелось к тому, что одному из заказчиков потребовалось выгружать данные из своей SAP ERP системы, путем манипуляций уже создавать отчеты и рассылки интересованным людям по email, а также другие действия.
Собственно, при обсуждениях решения такой задачи мы, как подрядчик, предлагали различные варианты и один из самых очевидных это все сделать именно с помощью внутреннего функционала SAP, по-простому среди «саперов» за Зедить все с помощью ABAP.
Первое с чем мы столкнулись, это не совсем прозрачные со слов заказчика критерии выборки данных, а именно, данные каких таблиц, зачем, почему, какие действия с ними необходимо совершить. Если привести пример, то заказчику нужна была выгрузка посещаемости сотрудников офиса, с данными в разрезе табеля и отпусков. Также нужно было создать отчеты по эффективности сотрудника с аналитикой по его времени на рабочем месте, не буду вдаваться в подробности, но скажу, что количество проведенного времени влияет на продуктивность, но что бы это выяснить нужно рассчитывать количество времени на работе с результатом работы и многое другое. Это только один из примеров отчета, а заказчик генерировал очень много в ходе обсуждений.
После долгих разговоров мы поняли, что таким решением может стать SAP Query или BI\BO, но заказчика не очень устроила рассчитанная стоимость решения и не самая удобная гибкость.
Решение на Python
Тут на свою голову я вспомнил об одной статье на ресурсе про библиотеку pyrfc и так-как я, не будучи программистом python, но читав о нем когда-то статьи решил изучить это дома, и к моему удивлению я с легкостью в домашних условия будучи дилетантом данного языка программирования обнаружил, что подключится к любой системе SAP невероятно просто более того это занимает 20 минут.
Двадцать минут КАРЛ!!!
Просто представьте, что можно настроить интерфейс подключения с ERP системой SAP без использования шин данных и всяких там PI\XI за такое крошечное время.
Реализация
Окончательно убедившись, что это вполне рабочее решение и удовлетворяет заказчика я изучил несколько платформ (изучил подразумевается почитал о каждой минут по 10) я выбрал среди прочих равных платформу Odoo, так как она проще развертывается и у нее есть все необходимые свойства, такие как: Хороший интерфейс, система прав доступа, мобильное приложение, почтовый сервер, хороший интерфейс с базой данных (psql).
Далее все очень просто.
Установить на виртуальную машину заказчика Odoo (я взял версию 8) т.к. она самая простая на текущий момент, знаю, что уже версия 12, но задача не требует всех крутых новинок.
Установил все необходимые библиотеки, в частности pyrfc — ссылка на статью посвящённую установке и подключению.
Далее необходимо было только написать небольшой модуль в самой платформе Odoo, для коннекта, а инструментов для визуализации данных у нее предостаточно.
Коннект к системе заказчика:
from pyrfc import Connection
user = 'user'
passwd = 'secretuser'
saprouter = '/H/192.168.0.140/S/3297'
conn = Connection(user=user, passwd=password,
mshost='CLient',
msserv='192.168.0.140',
sysid='01',
group="SPACE",
saprouter=saprouter,
client=‘900')
Вызов BADI для получения информации о юзере
b_result = conn.call('BAPI_USER_GET_DETAIL',
USERNAME = 'user',
CACHE_RESULTS = ' ')
Изменение юзера
updated_address['CITY'] = u'Moscow'
r = conn.call('BAPI_USER_CHANGE',
USERNAME='user',
ADDRESS=updated_address)
Самым главным инструментом для получения данных из SAP, если речь идет о таблицах, является функциональный модуль RFC_READ_TABLE, есть в SAP платформе и другие модули, которые можно вызвать, на них должна быть настройка, которая говорит о том, что их можно вызвать средствами RFC.
Например:
from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError
from ConfigParser import ConfigParser
from pprint import PrettyPrinter
def main():
try:
config = ConfigParser()
config.read('sapnwrfc.cfg') - #читаем конфиг, где лежат данные о логоне в систему SAP ERP
params_connection = config._sections['connection']
conn = Connection(**params_connection) #создаем коннект с системой
options = [{ 'TEXT': "FCURR = 'USD'"}]
pp = PrettyPrinter(indent=4)
ROWS_AT_A_TIME = 10
rowskips = 0
while True:
print u"----Begin of Batch---"
result = conn.call('RFC_READ_TABLE', \
QUERY_TABLE = 'TCURR', \
OPTIONS = options, \
ROWSKIPS = rowskips, ROWCOUNT = ROWS_AT_A_TIME)
pp.pprint(result['DATA'])
rowskips += ROWS_AT_A_TIME
if len(result['DATA']) < ROWS_AT_A_TIME:
break
except CommunicationError:
print u"Could not connect to server."
raise
except LogonError:
print u"Could not log in. Wrong credentials?"
raise
except (ABAPApplicationError, ABAPRuntimeError):
print u"An error occurred."
raise
Результат
На данной картинке список отчетов, которые выгружаются данным методом, и пример одного из них.
Итог
По большому счету данный метод открывает огромные возможности по замене очень дорогих инструментов SAP и других более гибкими и отрытыми.
Примеры кода взяты из открытых источников т.к. у меня нет прав на использования кода заказчика в статье, да и я не программист Python, мог где то и ошибся.
Хочу добавить, что данный инструмент мы уже применяем в очень большом спектре задач связанных с Расчетом KPI, вывод данных в другие источники (сайты, базы данных поставщиков и заказчиков), рассылка информации из систем на основе данных из SAP и многое другое.
Для меня вообще стало открытием вообще такая возможность, если у кого, есть похожий опыт я бы с удовольствием выслушал.
Спасибо!
C Уважением, Консультант SAP