Maximo Assetspec 自动化脚本缓慢和错误

Maximo Assetspec automation script slowness and error

下面是我的自动化脚本,它是资产加载过程的第二部分。第一部分在从外部系统创建资产时将属性数据加载到资产中,但它还设置了在 ASSETSPEC table 中创建记录的 CLASSIFICATIONID,这会触发以下脚本:

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 秒的停顿。而且我还收到一个 oracle 错误:

java.sql.SQLException: ORA-00904: "ASSETNUM": 无效标识符

我唯一引用 ASSETNUM 的地方是当我从 ASSETSPEC MBO 中检索字符串时,assetnum 是它的一个属性,所以我很困惑为什么会收到此错误。

我的问题是,为什么我会收到无效标识符错误,为什么会有暂停,它们是否已连接?

该脚本大约需要 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

这里有一些提高脚本性能的想法。我会将它们作为一般规则给出,然后举例说明如何应用它们。

规则:不要在你的脚本中做你可以让 Java 做的事情,因为编译的 Java 比你的脚本快。

应用程序:我不会从 mxserver 获取 gisAssetSet,而是在 AssetSpec 上建立关系并通过 mbo.getMboSet("relationship") 使用它。这让 Java 进行字符串操作,并让拥有的交易进行保存。

规则:设置和拆卸是昂贵的,所以尽可能减少和避免它们。

应用程序 1:我假设您使用的是对象发射点。在可能的范围内,使用对象事件条件来防止您的脚本在不应该的时候 运行。这避免了设置和拆卸。

应用程序 2:不在启动点上使用绑定变量,而是使用 mbo.get 方法。每个绑定的 Launch Point 变量都会产生大约 5 个额外的相关变量,这会增加设置和拆卸时间。您可以在 Scripting with Maximo 的隐式变量部分阅读更多相关信息。

规则:不要为同一个属性调用 mbo.getWhatever() 两次。

应用程序:在某些情况下,您会连续调用 getString("length_")。我认为如果您调用一次代码,将返回值缓存在一个变量中,然后多次使用该变量,您的代码会执行得更好。

就您收到的 Oracle 错误而言,我觉得我没有足够的信息。是否有其他脚本或交叉等在起作用?换句话说,你怎么知道这个错误是由这个脚本引起的?

希望对您有所帮助。

我试图重写您的代码,删除 ifs 并改用 elifs 来减少冗余。如果我处在你的位置,我会使用 ASSET 作为主要 mbo,并使用自定义 getMboSets 到达每个 ASSETSPEC mbo,以免 运行 sql 针对 ASSET table 命令 5 次对于每个 SPEC 记录。如果这两种方法都不起作用,最好在晚上使用升级和操作启动点 运行 您的代码。 顺便说一句,如果您使用的是 getMboSets,则也不需要 运行.save()。

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