0

I have some unexpected behaviour in an UpdateCursor. I'm iterating over quite a large dataset, and I've found that Python freaks out less if I break up the iteration into chunks:

env.workspace = r"ROADS.gdb"
arcpy.MakeFeatureLayer_management("JUNCTIONS", "jn_layer")

for i in range(-70000, 1500000, 10000):
    strFilter = "UFI >= " + str(i) + " AND UFI < " + str(i+10000)
    print strFilter

    with arcpy.da.UpdateCursor("jn_layer", ["OID@","UFI"], strFilter) as upCursor:
        for rowInt in upCursor:
            # do stuff

I would expect this to create a new cursor for each iteration with different filters, as per the print line:

UFI >= -70000 AND UFI < -60000
UFI >= -60000 AND UFI < -50000
UFI >= -50000 AND UFI < -40000
...etc

The problem is the first iteration works as expected, but each subsequent iteration of i returns no rows - it spits out each subsequent filter value but does nothing inside the with loop. Once it finishes, if I change the initial value:

for i in range(-60000, 1500000, 10000):

then it processes the first 10000 values (which were ignored before), but again the rest of the iterations of the with loop return no values. It feels like it's keeping the first filter on jn_layer and trying to apply the second filter to that filtered set, which of course returns no rows since there's no overlap between the ranges.

Is this the expected behaviour? I would have thought creating a cursor on a layer would only filter the layer for as long as the cursor exists, and the with keyword should be destroying the cursor before the filter changes...? Any advice would be most welcome.

10
  • 2
    Guessing at a possible solution: Perhaps del upCursor at the end of your for loop, to "reset" the cursor?
    – Erica
    Dec 8, 2014 at 12:52
  • it looks like a feature layer is being passed to the updateCursor - it's possible to apply a clause to that layer, which could either be a potential solution, or perhaps there is a clause applied to it already? Dec 8, 2014 at 13:01
  • Works as expected on my PC. I wouldn't use filter as variable though..
    – FelixIP
    Dec 8, 2014 at 20:12
  • 3
    #do stuff looks interesting. You cannot change OID and UFI used as definition query. What are you actually updating please, unless it is top secret
    – FelixIP
    Dec 9, 2014 at 0:56
  • 1
    Yes when working with layers, cursors deal with selection if any. I am ok with no credits, you've figured it yourself. One cannot edit OID, because this is internal database thing. I didn't mean UFI, but it seemed too risky thing to do for variable in def.query. happy pythoninh
    – FelixIP
    Dec 9, 2014 at 4:57

1 Answer 1

4

Thanks to @FelixIP for steering me in the right direction.

Inside the loop (where I had #do stuff) I was making a selection on "jn_layer":

arcpy.SelectLayerByAttribute_management("jn_layer", "NEW_SELECTION", "...")

When the loop exits and the new cursor is created, that selection is still active and the cursor searches the selection, not the whole layer. Explicitly clearing the selection ahead of the cursor:

arcpy.SelectLayerByAttribute_management("jn_layer", "CLEAR_SELECTION")
with arcpy.da.UpdateCursor("jn_layer", ["OID@","UFI"], strFilter) as upCursor:
    [...]

resolved the issue.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.