arcpy.da.UpdateCursor fails to update geometry

3918
12
Jump to solution
01-26-2017 05:25 AM
BledarBirbo1
Occasional Contributor

Hi.

I am having the following issue when i try to update an SDE Geodatabase featureclass geometry from arcpy

Using:

ArcGIS 10.3.1

SQL Server Geodatabase

Line featureclass with enabled: Archiving , Editor Tracking and Registered as Versioned.

The line featureclass also participates in a replica as the source layer.

The line fetureclass can be edited fine from arcmap.

The issue:

Because we do receive new updated line geometries (features) from another source i have bulid a python script that joins the 2 datasets based on an attribute key and and tries to update the geometry on the Line Featureclass.

I am using the following code tu update the geometry.

fieldNames = ['ID', 'SHAPE@','SHAPE@WKT']
edit.startEditing()
edit.startOperation()
with arcpy.da.UpdateCursor(line_layer, fieldNames) as updateCursor:
 for tmpRow in updateCursor:
    tmpRow[1] = #newgeometry that was read previusly
    updateCursor.updateRow(tmpRow)
edit.stopOperation()
edit.stopEditing(True)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The code runs without any error but the geometry is not updated. I tested the code for other attributes and they were updated correctly.

Any ideas ?

Thanks.

0 Kudos
1 Solution

Accepted Solutions
VinceAngelo
Esri Esteemed Contributor

kimo wrote:

Do you need a geometry AND a wkt version? Surely one will do. You would have to be careful to get the one in the list.

This is the key point.  By specifying an update of the same column in two different forms, but only updating the first referenced input, the code is likely updating the column with the new content, then updating it again with the previous contents.

Multiple references to the same geometry column in an UPDATE or INSERT cursor really ought to raise an error.

- V

View solution in original post

12 Replies
IanMurray
Frequent Contributor

after you set the values with the cursor for the row, you need to have cursor.updateRow(tmpRow), otherwise it doesn't save the values.

Add the following to a new line after the current line 6 with the same indent as line 6:

cursor.updateRow(tmpRow)

See https://pro.arcgis.com/en/pro-app/arcpy/data-access/updatecursor-class.htm example 1 for another example if needed.

BledarBirbo1
Occasional Contributor

Hi.

There is an update command i just forgot to copy it in this post.

So that do not help.

0 Kudos
KimOllivier
Occasional Contributor III

You have skipped the key item - what geometry are you adding? How did you get it? Is it really  a geometry?

I don't think you can join two featureclasses and retrieve both geometries at once. You are probably just replacing the geometry with itself.

I would create a python dictionary of source geometries keyed by the id using a list comprehension and a ReadCursor.

Then close the cursor and open an UpdateCursor and iterate over the list. You could even speed it up

by using an SQL query to only select records to be updated with an IN sql clause of the keys.

BledarBirbo1
Occasional Contributor

The geometry that is beeing assigned is not the same and is fine.

0 Kudos
KimOllivier
Occasional Contributor III

Ok, well how many features are in the layer definition?

Can you print out the ID and featurecount?

I assume you are using some sort of index based on the ID to get the respective geometry to add?

Why are you getting the geometry out twice in the updateCursor?

0 Kudos
BledarBirbo1
Occasional Contributor

There are 300 new features that are beeing read from a SearchCursor. 

Their geometry is then stored on a python list as Geometry object and as WKT plus the OBJECTID

During the UpdateCursor each feature is matched with the ones that were read before from the python list based on OBJECTID.  If matched then the 

 tmpRow[1] = objectlist[matchedindex] geometry.
#even constructing a new Geometry from the WKT like this does not work 
tmpRow[1] = arcpy.FromKWT(objectlist[matchedindex] wkt)

0 Kudos
KimOllivier
Occasional Contributor III

Is this too simple? If the geometry is WKT format then the insert should use tmpRow[2] not tmpRow[1] because the field spec you must have is SHAPE@WKT

0 Kudos
KimOllivier
Occasional Contributor III

Rather than a list of geometries a dictionary of geometries is more direct to insert.

0 Kudos
KimOllivier
Occasional Contributor III

Do you need a geometry AND a wkt version? Surely one will do. You would have to be careful to get the one in the list.

Would it not be easier to just write  row[1] = objectdict[row[0]] where the objectdict is a dictionary of shapes indexed by ID

I am trying to help you debug your code, so I would put in a lot of print statements that confirm you do have a geometry and it is

in the right row element by printing out a WKT representation as you go and then break after the first one.

If you only put up pseudocode you are hiding your problem with your assumptions on where the problem lies. It would be much better

if you posted your real code.