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")
下面是我的自动化脚本,它是资产加载过程的第二部分。第一部分在从外部系统创建资产时将属性数据加载到资产中,但它还设置了在 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")