problem with arcpy.da.updateCursor

861
4
Jump to solution
06-20-2014 04:32 AM
MarcListemann
New Contributor
I'm a programming-beginner and I am currently writing my first Python-Script. That's why the question is more a general (or perhaps a semantic) one. I want to write a specific ID to the attribute table of an existing shapefile. This ID is amongst others composed of the coordinates (centroid) of the shape. So I tried the following:
import arcpy   arcpy.env.workspace = "**************" outline = "***********testoutline7.shp" fields = ['SHAPE@XY']  with arcpy.da.SearchCursor(outline, fields) as cursor:       for row in cursor:             coordX = row[0][0]             if coordX < 0:                 coordX = coordX + 360             coordY = row[0][1]              print "X: {}, Y: {}".format(coordX,coordY)              #----transformation of the centroid-coordinates---#             Xrnd = round(coordX, 3)             longitude = str(Xrnd)             glimsLongitude = longitude.split('.')             Yrnd = round(coordY, 3)             latitude = str(Yrnd)             glimsLatitude = latitude.split('.')             #-----------------------------------------#              with arcpy.da.UpdateCursor(outline, "GLIMS_ID") as crsr:                 for glims in crsr:                       glims[0] = "G" + glimsLongitude[0] + glimsLongitude[1] + "E" + glimsLatitude[0] + glimsLatitude[1] + "N"                       crsr.updateRow(glims)


The problem is, that after processing there is the same ID in every polygon of the shapefile. I'm using only a test-shapefile to try it and it consists of 3 polygons. They all get the same ID in their attribut-field "GLIMS_ID". But the print-statement above on the other hand returns all the different coordinates of the different polygons. What's the mistake?
I know, the code requires a lot of revision and it is not yet beautiful. I would therefore be open-minded for every other suggestion for improvement. I also tried to vary the "position" of the last 4 lines, without success.

Thank you for your help!
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
Zeke
by
Regular Contributor III
Try not putting your Update code in its own loop. If necessary, retrieve the OID or other unique field in your SearchCursor as well as the current field. Use the OID in a Where clause in your UpdateCursor. This way you'll loop through the records in your SearchCursor, and target the record the SearchCursor is on in your UpdateCursor.

Or, you could try ditching the SearchCursor and just use an UpdateCursor, doing your calculation there before you call updateRow. I've never done this, but Help says UpdateCursor is read/write, so presumably it can function as a SearchCursor as well. The next() method returns a tuple of the values, so you should be able to read the necessary values out of that.

View solution in original post

0 Kudos
4 Replies
Zeke
by
Regular Contributor III
At a quick glance, you're looping through your SearchCursor, and within that SearchCursor you're looping through the UpdateCursor. So each time through the Search loop, you're updating all your data with the same set of data, the one row, of search results. If three loops through your SearchCursor returned a, b, c, respectively, your UpdateCursor then populates your field with all a's, then all b's, then all c's, respectively.
0 Kudos
MarcListemann
New Contributor
At a quick glance, you're looping through your SearchCursor, and within that SearchCursor you're looping through the UpdateCursor. So each time through the Search loop, you're updating all your data with the same set of data, the one row, of search results. If three loops through your SearchCursor returned a, b, c, respectively, your UpdateCursor then populates your field with all a's, then all b's, then all c's, respectively.


Ok, thank you, I guess i see what you mean. But do you therefore also have a solution? I tried to set the UpdateCursor-Method out of the SearchCursor-loop, but with the same effect. Is UpdateCursor probably the wrong approach for this purpose?
0 Kudos
Zeke
by
Regular Contributor III
Try not putting your Update code in its own loop. If necessary, retrieve the OID or other unique field in your SearchCursor as well as the current field. Use the OID in a Where clause in your UpdateCursor. This way you'll loop through the records in your SearchCursor, and target the record the SearchCursor is on in your UpdateCursor.

Or, you could try ditching the SearchCursor and just use an UpdateCursor, doing your calculation there before you call updateRow. I've never done this, but Help says UpdateCursor is read/write, so presumably it can function as a SearchCursor as well. The next() method returns a tuple of the values, so you should be able to read the necessary values out of that.
0 Kudos
MarcListemann
New Contributor
Great! I used your latter suggestion (but without the next()-method) and it worked! Just using the UpdateCursor without SearchCursor. It's actually that simple.
Many thanks!
0 Kudos