I have a script that I recently created an alternate copy of and updated many of the calculate field functions to make use of UpdateCursor. When I run the original script, all runs through just fine, but whenever I try to run the alternate version, the tool gets hung up on any of the parts that are still in CalculateField format. Is there a known issue with mixing UpdateCursors and CalculateField functions within the same script? Is there a common procedure that needs to be followed to do so? Sample code below.
Other than changing from CalculateField to UpdateCursor, the only other difference that I see that I made was moving some of the variables into the functions as global variables so I could use them outside of the function (I think I had to anyway...these sections started working after I did so).
######################### # Calculate Region ######################### # Start message arcpy.AddMessage("Determining the correct region field to be updated for all node features...") # Set local variables inTable = nodeFeatures cursor = arcpy.UpdateCursor(inTable) # Determine the correct region field to update def Get_node_regionField(): global node_regionField if carrier == "CUST1": node_regionField = "CUST1Region" elif carrier == "CUST2": node_regionField = "CUST2Region" elif carrier == "CUST3": node_regionField = "CUST3Region" elif carrier == "CUST4": node_regionField = "CUST4Region" elif carrier == "CUST5": node_regionField = "CUST5Region" else: pass Get_node_regionField() # Execute UpdateCursor for row in cursor: row.setValue(node_regionField, region) cursor.updateRow(row) # End message arcpy.AddMessage("The " + carrier + " region field has been updated for all node features!") arcpy.AddMessage("...") arcpy.AddMessage("...")
Each one of these IF statements used to be its own CalculateField (I didn't know how to incorporate them all into one, as I do above using the UpdateCursor method). The above code works just fine. I originally had the "node_regionField" variable as "inField", but there was an issue with doing so since I used inField for multiple other UpdateCursors. I'm assuming it had something to do with the fact that it is a global variable...? Not sure. Comment on that if you know, but the real issue is below:
######################### # Calulate latitude ######################### # Start message arcpy.AddMessage("Calculating the latitude values for all node features...") # Set local variables inTable = nodeFeatures inField = "Latitude" expression = "!Shape.Centroid.Y!" # Execute CalculateField arcpy.CalculateField_management(inTable, inField, expression, "PYTHON_9.3") # End message arcpy.AddMessage("The latitude values have been calculated for all node features!") arcpy.AddMessage("...") arcpy.AddMessage("...")
This code will not run, and all it does is return a generic 99999 error code:
"Traceback (most recent call last):
#my python script filepath#
arcpy.CalculateField_management(inTable, inField, expression, "PYTHON_9.3")
File "c:\program files (x86)\arcgis\desktop10.2\arcpy\arcpy\management.py", line 3354, in CalculateField
raise e
ExecuteError: ERROR 999999: Error executing function.
Failed to execute (CalculateField)."
This error code doesn't really tell me much. The weirdest thing is that it still works (copied identically) in the script that utilizes all CalculateField functions. I have 2 sections that calculate longitude, 2 that calculate latitude, 1 that calculates feet, 1 for meters, and 1 for miles. All 7 of them are constructed the same, and all 7 generate the same error message while in the mixed script, and all 7 work just fine in the all CalculateField version.
Side note...if the !shape.centroid@y! can be done using the UpdateCursor method (I couldn't figure out how), I would much rather that anyway.
Solved! Go to Solution.
Hi
You should use the da.UpdateCursor and use the "with" keyword (see docs).
Then the cursor close and release the table after it finished.
Then you can use the calculate.
In your code the cursor is not closed
Have fun
Mody
See this thread it has an example of populating fields Lat Lon populate x,y if you need a more straight forward example I'd be glad to help. Your first script, I don't see where your are declaring what carrier is but instead of the if elif statements i would use a dictionary see below.
carrierdict = {"CUST1":"CUST1Region","CUST2":"CUST2Region"} if carrier in carrierdict: carrier = carrierdict[carrier] else: arcpy.AddMessage("carrier not in dict")
Thanks for the helpful information, Wes. Looking at the link that you provided, I'm not really sure what's going on. From what I can tell the script allows the user to place the points and then the X/Y is auto-generated?
The carrier field is derived earlier in the script. I do believe, though, that the dictionary method that you reference above would work nicely instead of the way that I was doing it. Although your method does seem to be a quicker way to do it, the way I am doing it does work...it's the second code that I can't get to work.
As I mentioned in the original post, the second script works when used in my script that utilizes ALL calculate field methods. It's only when I try to use it while mixed in with UpdateCursors as well. I'm not sure if there is something between the two that throws one off or what. The theories that I can think of are the fact that I'm using global variables, maybe using UpdateCursors and CalculateField together in the same script creates some sort of conflict, or possibly the mix of the two creates a conflict between 32bit and 64bit processing...not sure. Those theories may not even hold water, but they're the only things I could think of when trying to figure out why it wouldn't run properly.
Hi
You should use the da.UpdateCursor and use the "with" keyword (see docs).
Then the cursor close and release the table after it finished.
Then you can use the calculate.
In your code the cursor is not closed
Have fun
Mody
I actually do use .da in other examples...maybe not in this exact script, though. I don't have access to that script to double check at this time, as it's on a different machine. If I use the .da version of UpdateCursor for every instance of UpdateCursor that I use, it will release the table for edits by other functions, such as CalculateField in my example?
If that is indeed the case then there is a conflict between using the two methods together, and it is corrected by using the .da version, correct? Just trying to make sure I am understanding you correctly.
Thanks!
The old cursor has a problem with release. It can be solved but it not always works.
When you use the "with" keyword with da cursors it's releasing the resources much better and it is also faster.
This should be always the way, no reason to use old cursors.
Here is a more straight forward example below. I don't see where you are deleting your cursor in your first script. That may be why your second is not working.
import arcpy fc = "your feature class here" ucur = arcpy.da.UpdateCursor(fc,["Shape@XY","Latitude"]) for row in ucur: x,row[1] = row[0] ucur.updateRow(row) del row, ucur
If you use the 'with' construction, you don't have to worry about deleting cursors:
with arcpy.da.UpdateCursor(fc,["Shape@XY","Latitude"]) as ucur: x,row[1] = row[0] ucur.updateRow(row)
He's not using with in his script he 's using for
You can use both, I think Greg Keith just forgot to add it in his code sample.
with arcpy.da.UpdateCursor(fc,["Shape@XY","Latitude"]) as ucur: for row in ucur: x,row[1] = row[0] ucur.updateRow(row)