I need to be able to use arcpy.da.Editor within the context of an existing ArcGIS Pro edit session. Is this possible or are the two completely separate?
Use Case:
Application where single workspace edit sessions are required. Datasets are traditional versioned. User has an edit session running to modify shapes and attributes. User then needs to run a Python script for an automated part of their workflow. That Python script updates a value in a record in one of the versioned datasets. User then decides to discard edits. That discard should also drop the change that the Python script made.
What I Have Tried:
Start editing in ArcGIS Pro via Edit tab | Edit button
Run this code:
myLayer = sys.argv[1] # Parameter with Data Type: Feature Layer
edit = arcpy.da.Editor(r'c:\path\mysde.sde')
edit.startEditing(False, True)
edit.startOperation()
with arcpy.da.UpdateCursor(myLayer, ['thefield'], "objectid = 1") as ucur:
for urow in ucur:
urow[0] = 'new value'
ucur.updateRow(urow)
edit.stopOperation()
edit.stopEditing(True)This results in the edits being made, but the Edit tab | Save button does not enable, which tells me the edits were not made within the existing ArcGIS Pro edit session.
I have also tried using arcpy.management.CalculateField, but if there is an ArcGIS Pro edit session when that is run, the Pro edit session gets stopped.
Is there any other way to edit attributes within the ArcGIS Pro edit session from Python?
Solved! Go to Solution.
Ahhhh I see, I was under the impression that you were having trouble getting the edit session to work at all.
You can use an existing edit session if one is active, but creating one with arcpy will create a new session which will conflict with the active one. If you've already created one in the UI, just skip creating one in arcpy.
Caveat is that this only works for non-versioned data that does not participate in a topology though, so I don't think it'll work for your needs.
You could get around that my copying the table to memory first, using the edit session, then applying the edits afterwards in a new session though.
Hey @Jeff-Reinhart
Have you tested without enabling the edit session? So basically everything you have without any edit variables? I've had some issues previously where the UpdateCursor won't run inside of an edit session that I've established, instead it tries to pull the original Pro edit session.
Cody
Thanks for the reply, @CodyPatterson
If I run without startEditing/stopEditing:
myLayer = sys.argv[1] # Parameter with Data Type: Feature Layer
edit = arcpy.da.Editor(r'c:\path\mysde.sde')
edit.startOperation()
with arcpy.da.UpdateCursor(myLayer, ['thefield'], "objectid = 1") as ucur:
for urow in ucur:
urow[0] = 'new value'
ucur.updateRow(urow)
edit.stopOperation()I get "RuntimeError: start edit session"
If I run with no arcpy.da.Editor and just the update cursor, I get:
"RuntimeError: Objects in this class cannot be updated outside an edit session."
Bear in mind, this is on versioned data, so I believe an edit session is required.
Have you tried using the editor context manager instead of creating a global object? E.g. just add Editor(*args) as edit to the with block?
If you run this code more than once, you'll create multiple editors while the context manager will clean up when it leaves scope
@HaydenWelch I guess I am not following. How would that affect whether arcpy.da.Editor is using the ArcGIS Pro edit session?
You may also need to set the multiuser_mode flag on your Editor object. The context is for cleanup since Editor objects can maintain locks and shouldn't be put on the global scope (they will maintain those locks indefinitely). Technically calling stopEditing() should clear the locks, but if you run your code and an exception is raised before the lock is cleared, the next run will have to deal with the uncleared lock.
Using a context manager makes sure that even if there's an error, the Editor object cleans itself up:
from arcpy.da import Editor, UpdateCursor
e = Editor(..., multiuser_mode=True)
e.startEditing()
with UpdateCursor(...) as cur:
...
<-- Exception Here
e.stopEditing() <-- Never Called
# e still maintains reference to an Editor in that workspace
# This can cause issues with locks not being removed
# Alternatively:
with (
Editor(..., multiuser_mode=True) as edit,
UpdateCursor(...) as cur
):
...do_stuff...
< -- Exception Here
Call edit.__exit__
raise Exception
# edit is gc'd as soon as we exit the with context block
# This will call the __exit__ method of Editor which clears locks
@HaydenWelch I agree that all of this garbage collection is important. But I am not seeing how it answers the initial question of whether an ArcGIS Pro edit session is accessible via Python or if they are completely separate.
Ahhhh I see, I was under the impression that you were having trouble getting the edit session to work at all.
You can use an existing edit session if one is active, but creating one with arcpy will create a new session which will conflict with the active one. If you've already created one in the UI, just skip creating one in arcpy.
Caveat is that this only works for non-versioned data that does not participate in a topology though, so I don't think it'll work for your needs.
You could get around that my copying the table to memory first, using the edit session, then applying the edits afterwards in a new session though.
Thank you for the confirmation. I had a lot of workflows in ArcMap that relied on Python being able to make edits within an existing ArcMap edit session. There is topology and all editable datasets are versioned. This change in ArcGIS Pro blows all of that up. 😥
There's been some movement by the arcpy team to make Python edit sessions and tools more extensive. You should put in an idea to attach the Pro edit session to the arcpy.mp.ArcGISProject object or add a da function that lists active editors on a database.
Being able to hook into the system editor would save me a ton of headache too, but all my tooling has been written for pro so I'm not effected