2

I have a string field within a GDB that does not accept all string values, giving a "The row contains a bad value" error. I have fixed the issue with InsertCursor (prompts user for new value), but can't with UpdateCursor.

The problem with UpdateCursor is that it does not actually give an error until the next iteration - at which point, any time I try to create a cursor object to the applicable table, I get a TypeError: 'NoneType' object is not iterable. Because of that, I cannot go back into the table and fix the value. (The type of the cursor is still an UpdateCursor object, but the error arises once I try to loop through it)

This is the code I originally had (I open an edit session earlier, for reference):

with arcpy.da.SearchCursor(pathDBF, fields_in) as cursorDBF:
    for rowDBF in cursorDBF:
        where = "{0} = '{1}'".format(name_field, rowDBF[nameIndex])
        with arcpy.da.UpdateCursor(pathGIS, fields_out, where_clause = where) as cursorGIS:
            for rowGIS in cursorGIS:
                while True:
                    try:
                        cursorGIS.updateRow(rowDBF)
                        break
                    except: 
                        rowDBF = fixRow(rowDBF)

This is my currently working fix (create new cursor and test if it's iterable; if not, fix row and update again). This feels really convoluted to me and I'm hoping someone can help me find a better way.

for rowGIS in cursorGIS:
    while True:
        cursor.updateRow(rowDBF)
        try:
            with arcpy.da.UpdateCursor(pathGIS, table.fields_out, where_clause=where) as cursorNew:
                for newRow in cursorNew:
                    break
            break
        except:
            rowDBF = fixRow(rowDBF)
  • 4
    A cursor inside a cursor isn't a good idea, perhaps we could help expand that to a dictionary and two disparate cursors; it looks like you're trying to update your shapefile with values from a table - have you considered a join/calculate field instead? or is there a reason why you should be cursoring? What is it that you're trying to update? What is fixRow? Why is it that you're trying to update the row before attempting to fix it? – Michael Stimson Dec 11 '17 at 23:16
  • It's an outside table updating values of an inside table. However, the inside table's field requirements may be more strict than the outside, so the outside may have invalid data. fixRow prompts the user to input valid data and replaces the invalid data with the new valid data (which is how I have it working for InsertCursor). Why I'm not fixing the data prior to updating is that I don't just want to fix this issue, but rather any possible issue that may arise that is similar in nature - what is 'invalid' can change, and I don't want to hard code a fix every time something comes up – selfname Dec 11 '17 at 23:27
  • 2
    The thing is, that if you update a row without changing it first you're just making the process slower. You can make a dictionary solution as reusable as a cursor/cursor solution thanks to pythons whimsical typing. You are aware that you can't prompt the user inside a geoprocessing tool as functions like input and raw_input do absolutely nothing in a tool dialog. – Michael Stimson Dec 11 '17 at 23:32
  • 2
    Your infinite loop construct is certainly not best coding practice. As a rule, you never want to make zero-change updates. Assuming the data table is not very-large (which would be exceedingly difficult to accomplish with a shapefile), changing the logic to cache to-be-changed rows in a dictionary the making a second pass with an update cursor is your best bet. – Vince Dec 12 '17 at 0:30
  • 1
    Alternatively, run a Frequency over your input table, identify and fix the bad values then Append all the records to the second table in one go...avoids the use of cursors and allows for bulk updates rather than fixing records one by one. – Dan Dec 12 '17 at 0:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.