Refresh Data after Python Tool Execution

1885
5
10-12-2020 11:52 AM
GlenColgate1
Occasional Contributor

By all documentation that I can find ArcPro should refresh the data in a map after running a custom geoprocessing tool. This has not been my experience so far. I have tried to make this tool several different ways. The edit completes successfully, but does not show in the map unless I refresh the map view in the versioning tools. Some think that the automatic refresh will be triggered if the tool has a derived output. Others have said that it will be triggered after the arcpy.da.Editor operation is closed as long as we are working in the "CURRENT" but not sure what that means in determining a workspace. The example below incorporated all of the documented recommendations without success.

All we want is a simple tool that updates a select number of attributes on an existing layer and saves them inside of the current version (shown in the map without additional action by user). Any recommendations appreciated.

Built with ArcPro 2.6.2 using the New Script wizard with a single input param and a single derived output param:

# Import system modules
import arcpy
# Set the parameters
InputIDF = arcpy.GetParameterAsText(0)
#Process: Start Edit
prev_workspace = arcpy.env.workspace
arcpy.env.workspace = arcpy.Describe('GPS').Path
edit = arcpy.da.Editor(arcpy.env.workspace)
edit.startEditing(False,True)
edit.startOperation()
arcpy.SelectLayerByAttribute_management('GPS', 'CLEAR_SELECTION')
with arcpy.da.UpdateCursor('GPS',['IDFEATURE','QAPNTUSE'],'IDFEATURE={}'.format(InputIDF)) as cursor:
 for row in cursor:
 row[0] = None
 row[1] = 5
 cursor.updateRow(row)
del cursor
# Cleanup
edit.stopOperation()
edit.stopEditing(True)
arcpy.ClearWorkspaceCache_management()
arcpy.env.workspace = prev_workspace
# Set layer as output param
p = arcpy.mp.ArcGISProject("CURRENT")
m = p.listMaps()[0]
l = m.listLayers('GPS')[0]
arcpy.SetParameter(1, l)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
5 Replies
GlenColgate1
Occasional Contributor

As a hack workaround, I added a CalculateField() call that populates a field with the same value it already had to trigger the refresh. 

# Run CalcField to trigger refresh
arcpy.SelectLayerByAttribute_management('GPS','ADD_TO_SELECTION','POINT_ID={}'.format(pid))
arcpy.CalculateField_management('GPS', 'ORAUSER','!ORAUSER!','PYTHON3')

This is not an acceptable solution, but will get us by until someone can figure out what I am doing wrong in the OP.

adminCentlec
New Contributor III

Hi, does this workaround work in cases of published gp tools? I have published quite a few of these but I am stuck here too as the output does not automatically refresh, it needs the user to refresh the web application in order for the changes to be posted. I am going to try this and perhaps post a similar question to ESRI as to why their RefreshTOC/RefreshActiveView and others do not work at all. 

0 Kudos
JeffLegato1
Occasional Contributor

I have a published GP tool that utilizes dynamic data and I can confirm that adding a calculate field pre-step to my published model seems to work. The obvious drawback is that it edits all the records so last_edited_date and last_edited_user fields are modified as well. Also, as the featureclass gets bigger it will take longer. 

JoshuaBixby
MVP Esteemed Contributor

I will start by saying this is definitely a continued weak spot for Pro. 

In terms of automatic refreshing, Pro does automatically refresh the map view when mapping-related items change, e.g., Contents pane changes, layers change, etc....  In this case, nothing map-related is changing, it is the data being referenced that is being changed.  The problem is that Pro has no idea the data has changed, so no refresh happens.  This problem/challenge is further complicated by the fact that Esri uses caching extensively in Pro, including for data behind layers.

This issue was terrible in the early days of Pro.  Esri has been addressing the issue, albeit in a piecemeal fashion and I would argue slowly.  Starting with ArcGIS Pro 2.0, Esri introduced the refresh button ( ) in the GUI so users could force Pro to refresh the map based on the current state of the data.  It wasn't until ArcGIS Pro 2.2 that Esri provided  SDK access to that functionality through the MapView.Redraw() and MapView.RedrawAsync() methods.  The redraw methods actually do more than force a refresh, they invalidate the cache for the layer, which forces Pro to revisit the data set, rebuild the cache, and refresh the screen.

So, where we are today is that users can manually override Pro's default behavior in the GUI, and developers can override it using the SDK, but there is no direct way to do it in Python/ArcPy.  Similar to how you can get under the hood of ArcGIS Desktop/ArcMap using Python comtypes or similar packages, you can do the same with Pro using Python.NET | pythonnet.github.io or similar packages.

My organization is considering integrating Python.NET into the base/default Pro Python deployment.  It is a hassle up front but opens the doors to so much more Pro functionality.  For example, solving your issue with Python.NET installed is as easy as:

# Import system modules
import arcpy
import clr

clr.AddReference("ArcGIS.Desktop.Mapping")
from ArcGIS.Desktop.Mapping import MapView

# Set the parameters
InputIDF = arcpy.GetParameterAsText(0)

#Process: Start Edit
prev_workspace = arcpy.env.workspace
arcpy.env.workspace = arcpy.Describe('GPS').Path
arcpy.SelectLayerByAttribute_management('GPS', 'CLEAR_SELECTION')
with arcpy.da.Editor(arcpy.env.workspace) as edit:
    with arcpy.da.UpdateCursor('GPS',['IDFEATURE','QAPNTUSE'],'IDFEATURE={}'.format(InputIDF)) as cursor:
        for row in cursor:
            row[0] = None
            row[1] = 5
            cursor.updateRow(row)

del cursor

# Cleanup
arcpy.env.workspace = prev_workspace

MapView.Active.Redraw(True)
YinghongLi1
Occasional Contributor

Hello  JoshuaBixby

This post is about two years old.  I'd like to know your experience using Python.Net now.

We have tools built by using ArcGIS ArcObject.  Some of them have heavy user interactions, e.g. in the middle of the tool execution a form pops up to let user do input or selection, which can not be done in python.  I am wondering if Python.Net allows developer to use window forms

thanks.  this is a great information. 

0 Kudos