I've created a Python add-in button that helps speed up my coworkers workflow by copying one feature class attribute to another. It uses the arcpy.UpdateCursor function to update a row in the target feature class. As it exists now, this button script can be run regardless of the editing mode. Obviously when its run in an edit session, the user can choose to stop editing and not save changes, but this is not the case when the script runs outside of an edit session.
How can I add a check to the script that will stop the script from running if ArcMap is not currently in an edit session?
This concerns ArcMap 10 & 10.1
I also want to check with other ArcMap users to verify that updates to tables is not normally allowed without being in an edit session.
So how is this script running outside of an edit session?
This script also brings up another question about the seemingly serendipitous selection order ArcMap performs that just happens to work for me when I update the 2nd feature class table from a list, but that's for another day.
Here's the script as it works now (without any 10.1 editor implementation):
How to add a check to ensure the user is in an edit session?
def onClick(self):
#Reference mxd
mxd = arcpy.mapping.MapDocument("CURRENT")
#Reference the main Data frame
mm = arcpy.mapping.ListDataFrames(mxd, "MainMap")[0]
#Reference the Water System Valve feature class
waterValves = arcpy.mapping.ListLayers(mxd, "Water System Valve", mm)[0]
#Reference the fire hydrant feature class
fireHydrants = arcpy.mapping.ListLayers(mxd, "Water Hydrant", mm)[0]
#Use the extent of the main DF to select all valves in the current view
dfAsFeature = arcpy.Polygon(arcpy.Array([mm.extent.lowerLeft, mm.extent.lowerRight, mm.extent.upperRight, mm.extent.upperLeft]), mm.spatialReference)
arcpy.SelectLayerByLocation_management(waterValves, "WITHIN", dfAsFeature,"", "NEW_SELECTION")
arcpy.SelectLayerByAttribute_management(waterValves, "SUBSET_SELECTION", "LOCATIONID IS NULL")
fields = ["LOCATIONID"]
row, rows = None, None
rows = arcpy.UpdateCursor(waterValves,fields)
row = rows.next()
valveList = []
append = valveList.append
#Loop through the valves table to update LocationID
while row:
builder = str(row.QSNO)+"-"+ str(row.VALVESEQNO)
row.setValue("LOCATIONID", builder)
append(builder)
rows.updateRow(row)
row = rows.next()
del row, rows
#New selection for fire hydrants
arcpy.SelectLayerByLocation_management(fireHydrants, "WITHIN", dfAsFeature,"", "NEW_SELECTION")
arcpy.SelectLayerByAttribute_management(fireHydrants, "SUBSET_SELECTION", "LOCATIONID IS NULL")
row, rows = None, None
rows = arcpy.UpdateCursor(fireHydrants,fields)
row = rows.next()
#Loop through fire hydrant table to update LocationID
while row:
for locID in valveList:
construct = str(locID) + "-FH"
#print construct
row.setValue("LOCATIONID", construct)
rows.updateRow(row)
row = rows.next()
del row, rows, valveList, mxd
Answer
So this is how I fixed my issue of not being able to control if someone using my tool was in an edit session or not:
#Reference to mxd and layers script here. Then...
try:
fields = ("OBJECTID")
upCursor = arcpy.da.UpdateCursor(waterValves, fields)
with upCursor as cursor:
for row in cursor:
pass
except:
pythonaddins.MessageBox('You are not in an edit session', 'Warning', 0)
else:
#Rest of script
The script works because it tries to create an UpdateCursor on a layer that has another UpdateCursor later in the script. This violates the behavior of the data access module. According to the ESRI Resources page on arcpy.da.UpdateCursor:
"Opening simultaneous insert and/or update operations on the same workspace using different cursors requires the start of an edit session."
I'm not happy with this solution because it's more of a hack than what I imagine is proper arcpy scripting. Better ideas anyone?
No comments:
Post a Comment