I am using ArcGIS Pro 2.9.3. I am a seasoned Python programmer, but need help meeting the following requirements:
I cannot figure out what combination of strings that arcpy.da methods need, given my environment. I will only know which map layer the user wants to work with at run-time. Its data source will be a feature class in a versioned dataset on an enterprise geodatabase. Given the variables below, which values will make arcpy.da methods happy, so I can Search, Update, Insert, and Delete rows from a layer, regardless of selection, and still be able to see those changes within the map?
projectName = "CURRENT"
project = arcpy.mp.ArcGISProject(projectName)
mapName = "Map"
map_ = next(filter(lambda m: m.name == mapName, project.listMaps()))
grpLayerName = "theGroup"
mapLayerName = "theLayer"
mapLayerLongName = "\\".join((grpLayerName, mapLayerName))
layer = next(filter(lambda lyr: lyr.longName == mapLayerLongName, map_.listLayers()))
dbName = "obfuscated"
schemaName = "adminUser"
datasetName = "bigDataSet"
datasetLongName = ".".join((dbName, schemaName, datasetName))
featClassName = "bigFeatureClass"
featClassLongName = ".".join((dbName, schemaName, featClassName))
sdePath = r"C:\Users\Myself\Documents\ArcGIS\Projects\BigProject"
sdeFileName = "enterprise.sde"
sdeFilePath = os.path.join(sdePath, sdeFileName)
desc = arcpy.da.Describe(layer)
# desc.catalogPath equals os.path.join(sdeFilePath, datasetLongName, featClassLongName)
# desc.path equals os.path.join(sdeFilePath, datasetLongName)
# SOMETIMES, however, an .sde file in a Temp path is seen, rather than the
# one in my project!
# desc.aliasName, baseName, file, and name all equal featClassLongName
arcpy.da.Editor(workspace argument?)
arcpy.da.UpdateCursor(in_table argument?)
I have tried so many combinations of strings for the workspace and in_table arguments, it's not even funny. I get errors like:
Any help, ideas, or guidance would be appreciated.
Solved! Go to Solution.
I was having some similar errors working off sde data a while ago but I determined that my editing session inputs were backwards so I would make sure that those are correct from the editor documentation. That should get rid of the "Objects in this class cannot be updated outside an edit session" and "cannot open workspace" errors. Not sure about the insufficient permissions though.
Also I believe that with versioned enterprise data another user will not be able to see edits you make to your version until there has been a rec and post unless they have access to your version. In that case I still believe they would have to refresh the connection due to the edits not being made during their own session. However, if you are making the edits within the python window and you cannot see the results until refreshing the connection, I'm not sure how to fix that bug.
This is a snippet of my code for a similar type of project that it seems you are attempting with the edit session inputs I used for sde data. Let me know if this helps or if I missed the mark entirely.
workspace = r"enterprise.sde"
edit = arcpy.da.Editor(workspace)
edit.startEditing(False, False)
edit.startOperation()
with arcpy.da.UpdateCursor(layername, "field") as cursor:
for row in cursor:
argument
edit.stopOperation()
edit.stopEditing(True)
Nicole
I had these same problems. Upgrading to ArcGIS Pro 3.0.3 was the fix for me.
I was having some similar errors working off sde data a while ago but I determined that my editing session inputs were backwards so I would make sure that those are correct from the editor documentation. That should get rid of the "Objects in this class cannot be updated outside an edit session" and "cannot open workspace" errors. Not sure about the insufficient permissions though.
Also I believe that with versioned enterprise data another user will not be able to see edits you make to your version until there has been a rec and post unless they have access to your version. In that case I still believe they would have to refresh the connection due to the edits not being made during their own session. However, if you are making the edits within the python window and you cannot see the results until refreshing the connection, I'm not sure how to fix that bug.
This is a snippet of my code for a similar type of project that it seems you are attempting with the edit session inputs I used for sde data. Let me know if this helps or if I missed the mark entirely.
workspace = r"enterprise.sde"
edit = arcpy.da.Editor(workspace)
edit.startEditing(False, False)
edit.startOperation()
with arcpy.da.UpdateCursor(layername, "field") as cursor:
for row in cursor:
argument
edit.stopOperation()
edit.stopEditing(True)
Nicole
Okay, but if layername is the name of a layer as it appears in the table of contents, it will have a selection, which I need to ignore for the various Cursors.
I spoke too soon. Here is the code that worked for me, based on what you said. Given a layer in a map, I can do this:
tableName = desc["catalogPath"]
fields = ["OBJECTID", "COMMENT"]
query = "OBJECTID IN ({0})".format(", ".join((str(objId) for objId in objectIds)))
eddy = arcpy.da.Editor(sdeFileName)
eddy.startEditing(True, True)
eddy.startOperation()
with arcpy.da.UpdateCursor(tableName, fields, query) as uCursor:
for row in uCursor:
row[1] = "Test Comment"
uCursor.updateRow(row)
del uCursor
eddy.stopOperation()
eddy.stopEditing(True)
del eddy
This will modify a row that is not part of a selection! Love it!
Glad you found a solution! I recommend testing your error handling here. If there's an error in your edit session, it may not close properly without a try/except statement or using a with statement.
My try blocks generally look like this:
eddy = arcpy.da.Editor(myWorkspace)
try:
eddy.startEditing(False, False) # Values depend on workspace
try:
# Operation 1
eddy.startOperation()
try:
with arcpy.da.UpdateCursor(in_table1, fields1, query1) as uCursor:
for row in uCursor:
# do something
uCursor.updateRow(row)
eddy.stopOperation()
except:
eddy.abortOperation()
raise
finally:
del uCursor
# Operation 2
eddy.startOperation()
try:
with arcpy.da.UpdateCursor(in_table2, fields2, query2) as uCursor:
for row in uCursor:
# do something
uCursor.updateRow(row)
eddy.stopOperation()
except:
eddy.abortOperation()
raise
finally:
del uCursor
eddy.stopEditing(True)
except:
eddy.stopEditing(False)
raise
finally:
del eddy
Updated to show how I now work my try/except/finally blocks. If anything goes wrong, the entire transaction is rewound and the database is left as it was, which makes this work well.
Hi Roger, did this edit the selected features in the default version? Or does it focus on only the version in the project?
That's a great question. I don't work with any other versions than DEFAULT and that's because I don't know how to make versions easy. In ArcGIS Desktop you had to modify your database connection (.sde) file and specify which version you were using. There was also a version toolbar. I think the version that is affected is the version used by the layer you're editing (if you specify a layer name for UpdateCursor) or the version tied to the .sde file if you're using a full-path to the feature class. It's worth testing for sure.
Most of what I know I found out by reading, asking, trying, and making lots of mistakes. If I was in your shoes, knowing this operation is important but volatile, I would set up some stuff. I'd create a test dataset, a few test feature classes, with a few fields, make the dataset versioned (and which kind?), and try these changes in your code. But a word of warning in determining if something worked or not: I have seen many cases where the change performed by Python isn't visible in the map, isn't visible after a refresh, isn't visible even after refreshing the version in the map, and isn't visible till after I close out Pro and reopen it. I don't know why.