Медлительность и ошибка скрипта автоматизации Maximo Assetspec

Ниже приведен мой скрипт автоматизации, который является второй частью процесса загрузки ассетов. Первая часть загружает данные атрибута в актив при создании из внешней системы, но также устанавливает CLASSIFICATIONID, который создает записи в таблице ASSETSPEC, которая запускает следующий скрипт:

from psdi.mbo import MboConstants
from psdi.server import MXServer
from psdi.security import UserInfo

username = "maxadmin"

mxServer = MXServer.getMXServer()
userInfo = mxServer.getUserInfo(username)

if mbo != None:
    mxAssetSpec = mbo

    AssetNum = mxAssetSpec.getString("assetnum")
    SiteID = mxAssetSpec.getString("siteid")

    gisAssetSet = mxServer.getMboSet(FEATURECLASS, userInfo)
    gisAssetSet.setWhere("mxassetnum = '" + AssetNum + "' and mxsiteid = '" + SiteID + "'")
    gisAssetSet.reset()

    gis = gisAssetSet.getMbo(0)

    if FEATURECLASS == "GRAVITYSEWERLINES":
        if ASSETATTRID == 'MATERIAL':
            mxAssetSpec.setValue("alnvalue", gis.getString("material"))
            mxAssetSpec.setValue("startmeasure", '0')
            mxAssetSpec.setValue("endmeasure", gis.getString("length_"))
            mxAssetSpec.setValue("startmeasureunitid", 'FT')
            mxAssetSpec.setValue("endmeasureunitid", 'FT')
        if ASSETATTRID == 'LENGTH':
            mxAssetSpec.setValue("numvalue", gis.getString("length_"))
            mxAssetSpec.setValue("startmeasure", '0')
            mxAssetSpec.setValue("endmeasure", gis.getString("length_"))
            mxAssetSpec.setValue("startmeasureunitid", 'FT')
            mxAssetSpec.setValue("endmeasureunitid", 'FT')
        if ASSETATTRID == 'INSTALL':
            mxAssetSpec.setValue("alnvalue", gis.getString("instalyear"))
            mxAssetSpec.setValue("startmeasure", '0')
            mxAssetSpec.setValue("endmeasure", gis.getString("length_"))
            mxAssetSpec.setValue("startmeasureunitid", 'FT')
            mxAssetSpec.setValue("endmeasureunitid", 'FT')
        if ASSETATTRID == 'ESTYEAR':
            mxAssetSpec.setValue("alnvalue", gis.getString("est_year"))
            mxAssetSpec.setValue("startmeasure", '0')
            mxAssetSpec.setValue("endmeasure", gis.getString("length_"))
            mxAssetSpec.setValue("startmeasureunitid", 'FT')
            mxAssetSpec.setValue("endmeasureunitid", 'FT')
        if ASSETATTRID == 'PDIAM':
            mxAssetSpec.setValue("numvalue", gis.getString("diameter"))
            mxAssetSpec.setValue("startmeasure", '0')
            mxAssetSpec.setValue("endmeasure", gis.getString("length_"))
            mxAssetSpec.setValue("startmeasureunitid", 'FT')
            mxAssetSpec.setValue("endmeasureunitid", 'FT')

    mxAssetSpec.save()
    mxAssetSpec.close()
    mxAssetSpec.resetForRefreshOnSave()

else:
    raise UnboundLocalError

Существует около 8 классификационных атрибутов, которые он циклически перебирает. Сам скрипт работает очень быстро, но между каждым классификационным атрибутом есть пауза около 3 секунд. И я также получаю ошибку оракула:

java.sql.SQLException: ORA-00904: "ASSETNUM": неверный идентификатор

Единственное место, где я ссылаюсь на ASSETNUM, — это когда я извлекаю строку из MBO ASSETSPEC, атрибутом которой является assetsnum, поэтому я не понимаю, почему я получаю эту ошибку.

Мои вопросы: почему я получаю ошибку неверного идентификатора и почему есть пауза, и они связаны?

Сценарий выполняется около 20 секунд и работает нормально, но 20 секунд — это примерно 19 секунд слишком долго. Любая помощь будет оценена по достоинству. Также будут оценены любые комментарии о том, как улучшить код.

Спасибо!

if mbo != None:
mxAssetSpec = mbo

mxAssetSet = mxAssetSpec.getMboSet("ASSET")
mxAsset = mxAssetSet.getMbo(0)
featureclass = mxAsset.getString("PLUSSFEATURECLASS")
assetattrid = mxAssetSpec.getString("ASSETATTRID")

print(featureclass)
print(assetattrid)

if featureclass == "GRAVITYSEWERLINES":
    gisAssetSet = mxAssetSpec.getMboSet("SPATIAL_GRAVITYSEWERLINES")
    gis = gisAssetSet.getMbo(0)
    length = gis.getString("length_")
    if assetattrid == 'MATERIAL':
        mxAssetSpec.setValue("alnvalue", gis.getString("material"))
        mxAssetSpec.setValue("startmeasure", '0')
        mxAssetSpec.setValue("endmeasure", length)
        mxAssetSpec.setValue("startmeasureunitid", 'FT')
        mxAssetSpec.setValue("endmeasureunitid", 'FT')
    if assetattrid == 'LENGTH':
        mxAssetSpec.setValue("numvalue", gis.getString("length_"))
        mxAssetSpec.setValue("startmeasure", '0')
        mxAssetSpec.setValue("endmeasure", length)
        mxAssetSpec.setValue("startmeasureunitid", 'FT')
        mxAssetSpec.setValue("endmeasureunitid", 'FT')
    if assetattrid == 'INSTALL':
        mxAssetSpec.setValue("alnvalue", gis.getString("instalyear"))
        mxAssetSpec.setValue("startmeasure", '0')
        mxAssetSpec.setValue("endmeasure", length)
        mxAssetSpec.setValue("startmeasureunitid", 'FT')
        mxAssetSpec.setValue("endmeasureunitid", 'FT')
    if assetattrid == 'ESTYEAR':
        mxAssetSpec.setValue("alnvalue", gis.getString("est_year"))
        mxAssetSpec.setValue("startmeasure", '0')
        mxAssetSpec.setValue("endmeasure", length)
        mxAssetSpec.setValue("startmeasureunitid", 'FT')
        mxAssetSpec.setValue("endmeasureunitid", 'FT')
    if assetattrid == 'PDIAM':
        mxAssetSpec.setValue("numvalue", gis.getString("diameter"))
        mxAssetSpec.setValue("startmeasure", '0')
        mxAssetSpec.setValue("endmeasure", length)
        mxAssetSpec.setValue("startmeasureunitid", 'FT')
        mxAssetSpec.setValue("endmeasureunitid", 'FT')

    mxAssetSpec.save()

еще: поднять UnboundLocalError


person TrojanMan78    schedule 14.10.2015    source источник


Ответы (2)


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

Правило: Не делайте в своем сценарии то, что вы можете заставить сделать Java, потому что скомпилированная Java быстрее, чем ваш сценарий.

Применение: вместо того, чтобы получать gisAssetSet от mxserver, я бы поместил связь в AssetSpec и использовал ее через mbo.getMboSet("relationship"). Это оставляет Java выполнять манипуляции со строками и владеющую транзакцию для сохранения.

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

Приложение 1: я предполагаю, что вы используете точку запуска объекта. Насколько это возможно, используйте условие события объекта, чтобы ваш сценарий не запускался, когда он не должен. Это позволяет избежать установки и демонтажа.

Приложение 2: вместо использования переменных связывания в точке запуска используйте метод mbo.get. Каждая связанная переменная точки запуска дает примерно 5 дополнительных связанных переменных, что увеличивает время установки и демонтажа. Подробнее об этом можно прочитать в Сценарии с Maximo, в разделе о неявных переменных.

Правило: не вызывайте mbo.getWhatever() дважды для одного и того же атрибута.

Применение: есть пара случаев, когда вы делаете последовательные вызовы getString("length_"). Я думаю, что ваш код будет работать лучше, если вы вызовете его один раз, кэшируете возвращаемое значение в переменной, а затем используете эту переменную несколько раз.

Что касается ошибки Oracle, которую вы получаете, мне кажется, что у меня недостаточно информации. Есть ли в игре другие сценарии, кроссоверы и т. д.? Перефразируя, как вы узнаете, что эта ошибка вызвана этим сценарием?

Надеюсь, это поможет.

person Preacher    schedule 15.10.2015
comment
Я добавил новый код выше, но между каждым атрибутом спецификации актива по-прежнему есть пауза в 3 секунды. Сам скрипт срабатывает за 16 мс, но время между срабатываниями для каждого атрибута спецификации объекта составляет около 3 секунд. Этот сценарий является второй частью процесса загрузки. Первый сценарий копирует информацию об атрибутах, а также устанавливает CLASSIFICATIONID, который, в свою очередь, запускает этот сценарий. - person TrojanMan78; 15.10.2015
comment
Не вызывайте mxAssetSpec.save(). Как правило, вы должны вызывать save() для MboSet только в том случае, если вы получаете MboSet от MXServer. - person Preacher; 15.10.2015
comment
Кроме того, просто из соображений стиля кодирования я бы не стал называть mbo mxAssetSpec. Для меня то, что я называю его просто mbo, напоминает мне, что оно было предоставлено Maximo и может относиться к разным объектам, в зависимости от точки запуска. - person Preacher; 15.10.2015
comment
Спасибо, но это все еще делает паузу около 3 секунд между каждым активатридом. Сам код работает очень быстро, но система буквально делает паузу около 3 секунд между каждым атрибутом. Он проходит через код для каждого атрибута assetspec. У меня есть демонстрационная система, на которой я также могу ее протестировать. Я попробую это и посмотрю, получу ли я те же результаты - person TrojanMan78; 15.10.2015
comment
Пауза все еще происходит даже без вызова save() в вашем коде? - person Preacher; 15.10.2015
comment
Я понял, почему это занимает 3 секунды между. Это было условие на стартовой точке. у меня было: номер актива в (выберите номер актива из актива, где plussfeatureclass не равен нулю). После того, как я удалил это, вся последовательность завершилась примерно за 1 секунду. Я также удалил вызов сохранения, но это ничего не сделало. Удаление условия запуска объекта также убрало ошибку ASSETNUM. - person TrojanMan78; 15.10.2015
comment
Выполнение (assetnum, siteid) в (select assetsnum, siteid... может ускорить выполнение вашего условия и сделать его более правильным. Или сопоставить его. - person Preacher; 15.10.2015

Я попытался переписать ваш код, удалив ifs и используя вместо этого elifs, чтобы уменьшить избыточность. Я бы использовал ASSET в качестве основного mbo, если бы я был на вашем месте, и использовал бы настраиваемые getMboSets для доступа к каждому mbo ASSETSPEC, чтобы не запускать команды sql для таблицы ASSET 5 раз для каждой записи SPEC. Если оба метода не работают, лучше запускать свой код ночью, используя эскалацию и точку запуска действия. Кстати, вам также не нужно запускать .save(), если вы используете getMboSets.

mxAssetSpec = mbo
mxAsset = mxAssetSpec.getMboSet("ASSET").moveFirst()
featureclass = mxAsset.getString("PLUSSFEATURECLASS")
assetattrid = mxAssetSpec.getString("ASSETATTRID")

if featureclass == "GRAVITYSEWERLINES" and assetattrid in ["MATERIAL","LENGTH","INSTALL","ESTYEAR","PDIAM"]:
    gis = mxAssetSpec.getMboSet("SPATIAL_GRAVITYSEWERLINES").moveFirst()
    if gis is not None:
        length = gis.getString("length_")
        if assetattrid == "MATERIAL":
            mxAssetSpec.setValue("alnvalue", gis.getString("material"))
        elif assetattrid == "LENGTH":
            mxAssetSpec.setValue("numvalue", length)
        elif assetattrid == "INSTALL":
            mxAssetSpec.setValue("alnvalue", gis.getString("instalyear"))
        elif assetattrid == "ESTYEAR":
            mxAssetSpec.setValue("alnvalue", gis.getString("est_year"))
        elif assetattrid == "PDIAM":
            mxAssetSpec.setValue("numvalue", gis.getString("diameter"))
        mxAssetSpec.setValue("startmeasure", "0")
        mxAssetSpec.setValue("endmeasure", length)
        mxAssetSpec.setValue("startmeasureunitid", "FT")
        mxAssetSpec.setValue("endmeasureunitid", "FT")
person Maximo_Junior    schedule 01.02.2021