UpdateCursor sequence error

547
14
Jump to solution
02-13-2021 08:56 AM
AdamGaudreau2
New Contributor III

Hey community,

Very infrequent poster here, so I'll try my very best to explain this with as much detail as possible. 

I'm trying to write a bespoke script tool for ArcGIS Pro (2.7) using Python (3.7).

I'm trying to use an UpdateCursor to update the rows of a .dbf table (outDBFTable). But when I run the script, I get the classic error "TypeError: sequence size must match size of the row". But when diagnostics 2 and 4 run, it appears the rows do in fact have the same number of elements. 

outDBFTable attributes:

OBJECTIDfield1field2field3field4...
1<Null><Null>...  
2<Null>...   
3...    
4     
5     
6     
7     

 

rasTable attributes:

OBJECTIDCount
1<number>
2...
3 
4 
5 
6 
7 

 

 

...

counter2 = 0
with arcpy.da.SearchCursor(inPoly,"SHAPE@") as sCursor2:
    for sRows2 in sCursor2:
        maskExtract = arcpy.sa.ExtractByMask(reclassRas,sRows2)
        rasTable = arcpy.management.BuildRasterAttributeTable(maskExtract) 
        arcpy.AddMessage(rasTable) # diagnostics 1

        with arcpy.da.SearchCursor(rasTable,("Value","Count")) as sCursor3:
            for sRows3 in sCursor3:
                arcpy.AddMessage(sRows3) # diagnostics 2

                with arcpy.da.UpdateCursor(outDBFTable,("OBJECTID",fieldList[counter2])) as uCursor1:
                    arcpy.AddMessage(uCursor1)# diagnostic 3
                    for uRows1 in uCursor1:
                        arcpy.AddMessage(uRows1) # diagnostics 4
                        if sRows3[0] == uRows1[0]:
                            arcpy.AddMessage("true true") # diagnostics 5
                            uCursor1.updateRow([sRows3[1]]) # <- Error raised here
                        else:
                            arcpy.AddMessage("false false") # diagnostics 6

        counter2 =+ 1

del (sCursor2)
del (sCursor3)
del (uCursor1)

...

 

Every time sCursor2 performs its task and produces a new rasTable, I want to use the "Count" column <number> from rasTable to update outDBFTable fields where outDBFTable "OBJECTID" == rasTable "OBJECTID". The counter is in there to position the cursor over the correct field from fieldList (field1, field2...) every time a new rasTable is produced. Mechanically, I'm confident all of this works because if I comment out  "uCursor1.updateRow([sRows3[1]])", the printout in the ArcGIS Pro tool message dialogue box behaves just as I expect. Or based on the error, I'm overly confident...

Basically, I don't understand why I'm getting a sequence size error when the diagnostics show the rows to be the same size.

I've attached a image of the error dialogue. 

Please let me know if more information is needed. 

 

Any help would be great!

0 Kudos
2 Solutions

Accepted Solutions
JeffK
by
Occasional Contributor III

If I follow it correctly, you are listing 2 fields in your update cursor, but passing only one to the updateRow. The parameter in the updateRow method needs to be the row.  If your conditional matches and then assign the field you want to update, then pass the row into the updateRow method.

 

 

 

for uRows1 in uCursor1:
    arcpy.AddMessage(uRows1) # diagnostics 4
    if sRows3[0] == uRows1[0]:
       uRows1[1] = sRows3[1] ???
    ...
    uCursor1.updateRow(uRows1)

 

 

View solution in original post

DavidPike
MVP Regular Contributor

I think its that you had =+ 1 rather than += 1 originally.  Well if it works it works.  I'm not entirely sure what it's fully doing, but I wonder if Zonal Statistics could have been an option.

View solution in original post

14 Replies
JeffK
by
Occasional Contributor III

If I follow it correctly, you are listing 2 fields in your update cursor, but passing only one to the updateRow. The parameter in the updateRow method needs to be the row.  If your conditional matches and then assign the field you want to update, then pass the row into the updateRow method.

 

 

 

for uRows1 in uCursor1:
    arcpy.AddMessage(uRows1) # diagnostics 4
    if sRows3[0] == uRows1[0]:
       uRows1[1] = sRows3[1] ???
    ...
    uCursor1.updateRow(uRows1)

 

 

View solution in original post

AdamGaudreau2
New Contributor III

Hi JeffK,

Thank you very much for your comments.

This definitely helps me in the right direction. Assigning sRows3 to uRows1 and passing that to updateRow method is what I needed to do to fix my sequence error. However, this first, and only the first, column was updated as expected. So I suspect, along with @DanPatterson, that there is something wrong with my counter.

 

I think it is only right to accept this response as the solution to my original question, but wanted to get @JeffK's and @DanPatterson's opinion on what I should do. If my problems with the counter persist (as I suspect they might because I've just tried trouble shooting and can't seem to get it to behave) should I repost or should I continue on this thread? 

 

Thanks

0 Kudos
JeffK
by
Occasional Contributor III

I'd start by nesting it under this for loop so when it reaches the uCursor field is incremented +1 for each iteration on sCursor3.

 

for sRows3 in sCursor3:
    counter2 += 1

 

I would also add the counter to some print statements or watch it in the debugger to see if it is incrementing as desired.  Not totally sure that will get you the desired output format, but its where I'd start testing.

edit to add you might also have to reset the counter to 0 when the iteration is complete, or move the variable assignment into a higher for loop so it auto rests to 0 on the next higher loop iteration.

0 Kudos
AdamGaudreau2
New Contributor III

Hi @JeffK,

I got it to work now. As in my replayed to @DavidPike, I was under the impression "var  = var + 1" worked the same way as "var =+ 1".  

0 Kudos
JeffK
by
Occasional Contributor III

Good to hear.  Like David said, You have the signs flipped, but if it works, it works.  - you can also accept multiple solutions.

0 Kudos
AdamGaudreau2
New Contributor III

Hi @JeffK,

Yes I did get the symbols flipped. I'll go back in, change it, and do some more testing. 

 

Thank you for your all of your help. 

0 Kudos
DavidPike
MVP Regular Contributor

As Dan says, your counter is likely in the wrong indent.  imho this nested approach and passing list indices via counter is just asking for headaches and nightmares.

0 Kudos
AdamGaudreau2
New Contributor III

Hi @DavidPike,

Thank you very much for your comment.

I just got it to work. The indent was actually in the correct spot from the original post. I guess I was incorrectly using "=+1". I should have simply been using "counter2 = counter2 + 1". I was under the impression these functioned in the same way. But swapping them out gives me the results I'm looking for. 

 

0 Kudos
DavidPike
MVP Regular Contributor

I think its that you had =+ 1 rather than += 1 originally.  Well if it works it works.  I'm not entirely sure what it's fully doing, but I wonder if Zonal Statistics could have been an option.

View solution in original post