ЛОЦМАН: Пишем свой WorkFlow-конфигуратор. Начало

в 9:30, , рубрики: pypyodbc, pyside, python, qt, sql, системное администрирование

Введение

Я работаю в организации, которая начала внедрять ПО от компании АСКОН, если быть точным, то «Комплекс решений АСКОН 2013» (далее «Комплекс») + КОМПАС. Я занимаюсь администрированием этого «Комплекса». «Комплекс» имеет трехуровневую архитектуру (Клиент-Сервер приложений-Сервер БД). Ключевым продуктом «Комплекса» является ЛОЦМАН:PLM, также имеется набор утилит администрирования. Одна из утилит администрирования называется «ЛОЦМАН WorkFlow Конфигуратор» (далее WF-конфигуратор).

image
Рисунок 1 — ЛОЦМАН WorkFlow конфигуратор

В ходе работы были выявлены основные недостатки WF-конфигуратора:

  • Нет русскоязычного поиска по ФИО, есть только по логину (причем только в виде доменлогин, кстати в «Центре управления комплексом», там где добавляются пользователи в систему, вообще нет никакого поиска...);
  • При большом количестве пользователей (>1K) он стал ужасно тормозить (около 4 минут на операцию добавления пользователя).

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

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

Чтобы исключить предполагаемые задержки, решил напрямую работать с базой, минуя «Сервер приложений». После анализа (пришлось вручную смотреть содержимое таблиц), были определены несколько таблиц (wfActors,wfDepartments,wfRoles,wfUserRoles), в которых хранятся нужные данные. В итоге процедура добавления пользователя в должность свелась к тому, что нужно добавить запись всего в 1 таблицу (wfUserRoles), которая содержит записи вида (inIdUser,inIdRole,dtStart,dtEnd):

  1. inIdUser — id пользователя;
  2. inIdRole- id роли (должность);
  3. dtStart — дата начала;
  4. dtEnd — дата окончания.

Если в полях даты начала/окончания стоит NULL, значит, срок действия пользователя в должности не ограничен.

Алгоритм действий получился следующий:

  1. Находим id-пользователя select * from wfActors where stDescription like 'Фамилия%' order by stDescription, результат — таблица с полями id-пользователя, русскоязычное имя пользователя. Запоминаем id-пользователя;
  2. Находим, в какое подразделения надо добавить пользователя select * from wfDepartments, результат — таблица с полями id-подразделения, название подразделения, id-родителя подразделения. Запоминаем id-подразделения;
  3. Находим должность в нужном подразделении select * from wfRoles where inIdDepartment = id-подразделения(из пред. шага), результат — таблица с полями id-должности, id-подразделения, название должности, запоминаем id-должности.
  4. теперь у нас есть id-пользователя и id-должности (в нужном подразделении), остается только добавить запись в таблицу insert into wfUserRoles values (id-пользователя, id-должности,null,null).

Даже выполняя эти SQL-запросы в Managment Studio, добавить пользователя получалось быстрее, чем через WF-конфигуратор. Затем был написан скрипт на Python, который выполнял все эти действия в консоли.

Следующий шаг — разработка GUI к этому скрипту, проанализировав какие из GUI библиотек есть для Python я выбрал PySide.

На домашнем компьютере было установлено следующее:

1) Установлено в виртуалку:

  • Windows Server 2008 R2;
  • MSSQL-сервер 2008 R2;
  • «Комплекс» АСКОН 2013.

2) Установлено на компьютер:

  • Python 3.4.1;
  • модуль pypyodbc;
  • модуль Pyside.

После того, как все установлено, можно приступать к разработке.

Нарисовал в QT Designer форму для приложения, сохранил в файл с расширением .ui.

В PySide есть отличный инструмент pyside-uic.exe, с помощью которого из ui-файла можно сделать файл.py. Для этого достаточно в консоли выполнить следующую команду: pyside-uic.exe file.ui -o file.py. Если указать еще аргумент -x, то этот file.py можно сразу запускать на выполнение и отобразится форма, нарисованная в Designer-е. Я об этом параметре (-х) узнал немного позже, когда уже воспользовался инструкциями с сайта zetcode.com/gui/pysidetutorial/, поэтому мой код немного отличается от сгенерированного с помощью pyside-uic.exe file.ui -x -o file.py.

Вот какая форма у меня получилась:

image
Рисунок 2 — My WorkFlow Configurator

Использовал библиотеку pypyodbc для работы с базой данных, PySide для работы с формой.

Получилось 3 файла:

  1. отрисовка GUI и привязка событий с формы к различным функциям;
  2. класс для работы с БД
  3. просто текстовый файл из которого загружаются начальные настройки для формы (и сохраняются при выходе)

Для добавления пользователя в должность необходимо сначала соединиться с базой кнопка «Connect» (логин и пароль пока прописан прямо в код программы), появится дерево «Структура организации», можно развернуть элементы если у них есть вложенные (1 клик) и перейти в выбранный элемент (двойной клик), после этого выбрать должность. Найти пользователя по Фамилии (кнопка «Search»), выбрать найденного пользователя и нажать кнопку «INSERT» (должна быть выбрана должность в дереве и пользователь в поле результатов поиска).

Интересным моментом стало построение дерева, до этого момента я с этим не сталкивался. Хочется написать как-то проще, но пока так формирую список элементов.

        treeItems=[]        
        for l in sorted(list1):
            parent=str(l[2])
            itemId=str(l[0])
            descr=str(l[1])
            treeItem=QtGui.QTreeWidgetItem([descr,itemId,parent])
            treeItems.append(treeItem)
        treeItemsFin=[]
        i=1
        for item in treeItems:
            for itemj in treeItems[i:]:
                if item.text(1)==itemj.text(2):
                    item.insertChild(0,itemj)
            i+=1
            treeItemsFin.append(item)

        self.treeWid.insertTopLevelItems(0,treeItemsFin)

Сначала из обычного списка (с элементами вида: [id-элемента,description,id-родителя]) формирую список из объектов типа QTreeWidgetItem (первый цикл), а затем из этого списка формирую другой список элементов, типа QTreeWidgetItem, но уже с вложенностью.

Пока намерено отказался от отображения уже добавленных пользователей, потому что мне кажется, что в этом проблема WF-конфигуратора АСКОН-а, у них после каждой операции обновляется все дерево и это занимает очень много времени.

В дальнейшем планирую сделать отображение пользователей только в выбранной ветке.

Пока этим приложением пользуюсь только я, но, возможно, другим администраторам пригодится… Для работы приложения необходим Python, PySide, pypyodbc установленные на компьютере администратора, в отличии от WF-конфигуратора от АСКОН, является кроссплатформенным.

Итоги

Из плюсов, поражены основные цели:
+ русскоязычный поиск по пользователям;
+ быстрое время работы.

Минусы:
— не отображаются должности если они находятся в корне дерева (т.е. ни в одном из подразделений, планирую доработать);
— не отображаются в дереве уже добавленные пользователи (планирую доработать);
— нет функционала создания/удаления подразделения, должности (планирую доработать);
— нет функционала бизнес-процессов, автоматических операций и др. что есть в WF-конфигураторе АСКОН-а (в ближайшем будущем не планирую это добавлять, поскольку этим пользуюсь не так часто и вроде нормально работает).

На этом пока все, исходники на github.com.

Список использованных источников

zetcode.com/gui/pysidetutorial/
deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/index.html
www.pythoncentral.io/pyside-pyqt-tutorial-using-built-in-signals-and-slots/

Автор: be1ay

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js