1

I originally asked UpdateCursor can't acquire lock, but can acquire lock in TestSchemaLock and got some help about why my code wasn't acquiring a lock.

My new problem is that my code isn't fully iterating, and I'm not sure why. My intention is that when I select each buffer used for clipping, I want the buffer to run a clip, create a clip output with that name, add and calculate fields, and then move on to create the next clip. There are 27 buffers (buff_id numbered 1 through 27), so that each clip output should be called "LS[buff_id]". It runs through LS1 just fine, giving me exactly what I expect, with the fields calculated, but then it doesn't move on to buff_id 2 to give me LS2 and so on.

What am I doing wrong?

Here's the code I'm using now:

import arcpy
import os.path
arcpy.env.workspace = "C:/Users/melis/Documents/HenryWork.gdb"
arcpy.env.overwriteOutput = True
buffer = "LS_buffer"
landcov = "ForestLC_clip"

#create list to access table. may need to change field name with other data. builds a list of all buff_id values.
AllBuffID = [r[0] for r in arcpy.da.SearchCursor(buffer, ["buff_id"])]

for thisBuffID in AllBuffID:
    #select one buffer
    query = """ "buff_id" = %s """ %thisBuffID
    arcpy.SelectLayerByAttribute_management(buffer, "NEW_SELECTION", query)

    #define clip out path
    clip_out = "LS" + str(thisBuffID)

    #clip w one buffer
    arcpy.Clip_analysis(landcov, buffer, clip_out)

    #add fields to clip_out
    arcpy.AddField_management(clip_out, "clip_id", "TEXT", 20)
    arcpy.AddField_management(clip_out, "area_ha", "FLOAT")

    #create updatecursor for new clip_out
    with arcpy.da.UpdateCursor(clip_out, ["clip_id", "area_ha","SHAPE@"]) as clipCursor:
        for polys in clipCursor:
            #calc geom for area ha, project to UTM and calculate from the area
            polys[1] = (polys[2].area) / 10000 #A hectare is 10000 square metres

            #field calc for buffer id
            polys[0] = thisBuffID
            clipCursor.updateRow(polys) #IMPORTANT commit the update
PolyGeo
  • 65,136
  • 29
  • 109
  • 338
Melissa
  • 165
  • 1
  • 9
  • 3
    is "LS_Buffer" a feature layer, and does it have a selection prior to running the script? If there is a selection on the feature, only selected features will be processed. SelectLayerByAttribute takes a feature layer as input, but I don't see in your code whether it is a feature layer or name of feature class. Perhaps add MakeFeatureLayer before or in place of the SelectLayerByAttriute. – Barbarossa Feb 01 '19 at 15:58
  • 3
    I would put in a print statement after you create the list AllBuffID to confirm it's contents. – Hornbydd Feb 01 '19 at 16:15
  • @Hornbydd - Thanks. It prints "[1]". So I had a SearchCursor there originally, but I understand now that it's bad practice to put a cursor within a cursor because it creates a schema lock. So the guy who helped me in my last post suggested using that list instead. By any chance can you suggest a better way to do that? – Melissa Feb 01 '19 at 18:22
  • If it is returning just 1 then that is the only ID in your LS_buffer layer. So you only have 1 row in your layer, but from the question you are asking you are expecting more? Maybe the source of the problem lies in the fact you may have a multipart dataset? 1 row in a table but many parts which you are interpreting as individual buffers? Easiest way to confirm this is to use the select tool and click on 1 polygon, if they all highlight then you have a multipart feature. Use the multi to single part tool to explode these into separate features (rows). – Hornbydd Feb 01 '19 at 21:38

1 Answers1

1

I suspect that you have a selection on your layer when your script is run. If this is the case only selected features will be run.

A couple solutions -

1) Clear selection prior to determining your buffer IDs:

arcpy.SelectLayerByAttribute_management (buffer, "CLEAR_SELECTION")
AllBuffID = [r[0] for r in arcpy.da.SearchCursor(buffer, ["buff_id"])]

2) Reference the underlying feature class for determining buffer IDs:

fc = arcpy.Describe (buffer).featureClass.catalogPath
AllBuffID = [r[0] for r in arcpy.da.SearchCursor(fc, ["buff_id"])]
Emil Brundage
  • 13,859
  • 3
  • 26
  • 62