I am trying to use the updateCursor but with little luck... What I would like to do is copy field values from an existing field in the table to a newly created field in the table. The issue I am having is that some tables have different name values and field types. I wonder if I am overcomplicating the whole issue or if I am setting something up incorrectly. I am just not sure at this point. Any insight and help with this will be greatly appreciated!
I am getting error 999999 on "return convertArcObjectToPythonObject(self._arc_object.GetValue(*gp_fixargs(args)))".
for filename in filenames: if fnmatch.fnmatch(filename, "*Anno*") == True: print "Skipped annotation file: " + filename elif fnmatch.fnmatch(filename, "*grid*") == True: print "Skipped grid file: " + filename else: #LOOP FIELDS fieldList = arcpy.ListFields(os.path.join(dirpath, filename)) for field in add_Fields: if field[0] in [f.name for f in fieldList]: print "Field name: " + field[0] + " exists in " + filename + " DO NOT ADD" else: print "Adding " + field[0] + " name to table " + filename arcpy.AddField_management(*(os.path.join(dirpath, filename),) + field) #create field search list possibleSearchFields = ["ENG_NAME", "Name"] updateField = ["New_Name"] searchFields = [] #Loop through possibleSearchFields for psf in possibleSearchFields: if psf in [f.name for f in fieldList]: #add to searchFields searchFields.append(psf) #LOOP ROWS cur = arcpy.UpdateCursor(os.path.join(dirpath, filename)) for row in cur: for searchField in searchFields: if row.getValue(updateField) == None: print searchField + "exists in the table and is updating: " + filename row.setValue(updateField, row.getValue(searchField)) else: print " No name field in the search list: " + filename
Thank you
Chris
This could be as simple as the fact that updateField is a list with one item, and the argument it is expecting is a string, not a list.
Try either changing
if row.getValue(updateField) == None:
to
if row.getValue(updateField[0]) == None:
or changing your updateField variable to a string, not a list with a single string in it.
That did indeed get me through the loop (sometimes it's the most obvious stuff)! But it does not update the field when I add:
cur.updateRow(row)
Thoughts?
There's some good information in this thread that might help you.
To simply things, You could probably just look at using Calculate Field instead of an update cursor. Also, take another look at how you're adding your fields; Your syntax looks strange and I don't see where you specify the field type. Finally, since you are joining the dirpath and filename a lot, might be easier to just make a variable at the beginning for your full file path.
I haven't tested this, but here's some code that hopefully portrays some of my ideas. I also created a dictionary (addFields) where the key is the new field name and the value is the possible search fields.
addFields = { "New_Name": ["ENG_NAME", "Name"], "Another_New_Field": ["PossibleSearchField1", "AnotherPsblSrchFld", "MaybeAnotherPSF"], "New_Fld": ["SimilarName", "Other_Existing_Fld"] } filepath = os.path.join(dirpath, filename) fieldsExisting = [f.name for f in arcpy.ListFields(filepath)] for addField, psf in addFields.items(): if addField not in fieldsExisting: # Adjust AddField parameters as needed arcpy.AddField_management( filepath, ## in_table addField, ## field_name "TEXT", ## field_type "", ## field_precision "", ## field_scale 12 ## field_length ) psfMatch = set(fieldsExisting) & set(psf) ## Compare lists and return matches in a set if len(psfMatch) == 1: matchField = next(iter(psfMatch)) ## Get field name from psfMatch set arcpy.CalculateField_management( filepath, ## in_table addField, ## field "!{}!".format(matchField), ## expression "PYTHON_9.3" ## expression_type ) else: print "More than one possible search field match, unable to caclulate field."
This doesn't attempt to convert field datatypes. I was just writing out some ideas.
Thank you for the reply, I will have a look at your suggestions. I will give it a go with calc field though. Thanks!
For my addFields I am using a tuple with no issues.
add_Fields = [("New_NAME","TEXT","","","254","","NULLABLE","NON_REQUIRED","")] arcpy.AddField_management(*(os.path.join(dirpath, filename),) + field)
I am running into problems when I try to update the new field with the old value.
#create field search list possibleSearchFields = ["ENG_NAME"] updateField = ["SL_NAME"] searchFields = [] #Loop through possibleSearchFields for psf in possibleSearchFields: if psf in [f.name for f in fieldList]: #add to searchFields searchFields.append(psf) #LOOP ROWS cur = arcpy.UpdateCursor(os.path.join(dirpath, filename)) for row in cur: for searchField in searchFields: #if value of field not blank, set updateField's value in row. also exit out of row loop if row.getValue(updateField[0]) == None: print searchField + "exists in the table and is updating: " + filename row.setValue(updateField[0], row.getValue(searchField)) cur.updateRow(row) print "Updated row: " + str(row) + " in " + filename else: print " No name field in the search list: " + filename
Oh, ok, now I see what you're doing with AddField.
The version of the update cursor you are using is actually an old method and is being replaced by the one using the data access module (arcpy.da). It might be worth transitioning to arcpy.da.UpdateCursor to see if maybe that solves your issue.
I'm going to agree with Blake, the new cursors are much more managable(not to mention much faster) for doing what you are needing to do. Never used the old style ones to be honest.
What might be the problem is it seems your indentation is off from what you were previously using for that particular if statement. You indented 8 spaces instead of 4 like the rest of your script(indentation on the else statement below seems correct), so it might be skipping the inside of your if statement? Or it could be the syntax highlighting in the forum.
I guess I will look into using the arcpy.da.updateCursor... Thank you Ian and Blake for the help!
Best
Chris
here is a simple script to create a field and copy values from an existing field.
import arcpy fc = "<my Feature Class>" fields = ('Length','mylength') arcpy.AddField_management(fc,"myLength","LONG") with arcpy.da.UpdateCursor(fc, fields) as cursor: mySharedField = 0 print mySharedField for row in cursor: mySharedField = row[0] print mySharedField row[1]= mySharedField cursor.updateRow(row) del row del cursor