Search code examples
oracleautomationjythonmaximo

Maximo Assetspec automation script slowness and error


Below is my automation script that is the second part of an asset loading process. The first part loads attribute data to the asset upon creation from an external system but it also sets the CLASSIFICATIONID which creates records in the ASSETSPEC table which fires the below script:

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

There are about 8 classification attributes that it cycles through. The script itself runs very fast but there is a pause of about 3 seconds between each classification attribute. And i also get an oracle error:

java.sql.SQLException: ORA-00904: "ASSETNUM": invalid identifier

The only place i am referrencing ASSETNUM is when i am retrieving the string from the ASSETSPEC MBO which assetnum is an attribute of so i am confused why i am getting this error.

My questions are, why am i getting the invalid identifier error and why is there a pause, and are they connected?

The script takes about 20 seconds to complete and works fine but 20 seconds is about 19 seconds too long. Any help would be appreciated. Also any comments on how to improve the code would be appreciated.

Thanks!

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()

else: raise UnboundLocalError


Solution

  • Here are a few ideas to improve the performance of your script. I'll give them as general rules and then give examples of how to apply them.

    Rule: Don't do in your script what you can make Java do, because compiled Java is faster than your script.

    Application: Instead of getting the gisAssetSet from mxserver, I would put a relationship on AssetSpec and use that via mbo.getMboSet("relationship"). This leaves Java to do the string manipulation and the owning transaction to do the saving.

    Rule: Set-up and tear-down are expensive, so reduce and avoid them to the extent possible.

    Application 1: I'm assuming you're using an Object Launch Point. To the extent possible, use an Object Event Condition to prevent your script from running when it shouldn't. This avoids set up and tear down.

    Application 2: Instead of using bind variables on your Launch Point, use mbo.get method. Each bound Launch Point variable results in about 5 extra, related ones which increases setup and teardown time. You can read more about this in Scripting with Maximo, in the section on implicit variables.

    Rule: Don't call mbo.getWhatever() twice for the same attribute.

    Application: There are a couple of cases where you make consecutive calls to getString("length_"). I think your code will perform better if you call it once, cache the returned value in a variable, then use that variable multiple times.

    As far as the Oracle error you are getting, I feel like I don't have enough information. Are there other scripts or crossovers or etc at play? Rephrased, how do you know this error is being caused by this script?

    I hope that helps.