Select to view content in your preferred language

Error using row.getValue()

8224
8
03-30-2015 08:33 AM
ChrisBrannin
Regular Contributor

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

0 Kudos
8 Replies
IanMurray
Honored Contributor

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.

ChrisBrannin
Regular Contributor

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?

0 Kudos
BlakeTerhune
MVP Regular Contributor

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.

ChrisBrannin
Regular Contributor

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
0 Kudos
BlakeTerhune
MVP Regular Contributor

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.

IanMurray
Honored Contributor

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.

0 Kudos
ChrisBrannin
Regular Contributor

I guess I will look into using the arcpy.da.updateCursor... Thank you Ian and Blake for the help!

Best

Chris

0 Kudos
CarlSunderman
Frequent Contributor

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