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:
OBJECTID | field1 | field2 | field3 | field4 | ... |
1 | <Null> | <Null> | ... | ||
2 | <Null> | ... | |||
3 | ... | ||||
4 | |||||
5 | |||||
6 | |||||
7 |
rasTable attributes:
OBJECTID | Count |
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!
Solved! Go to Solution.
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)
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.
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)
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 @Anonymous User'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
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.
Hi @Anonymous User,
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".
Good to hear. Like David said, You have the signs flipped, but if it works, it works. - you can also accept multiple solutions.
Hi @Anonymous User,
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.
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.
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.
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.