Using Update Cursor in For Loop - error

390
7
Jump to solution
03-13-2013 12:07 PM
RachelAlbritton1
New Contributor III
I am trying to use an update cursor ina for loop and I keep getting an IOError that I don't understand.

The script is looping through my table, selecting records one by one, then doing a select by location to fins out how many buffers intersect the selected record. The number of buffers that intersect that record need to be recorded in the attribute table. A sub-set of my code and error statements are below.

RCWfieldList = ["three_mi","avg_gs","PGB_avg","one_25mi","pot_hab"] ParcelFieldList=arcpy.ListFields(parcelsFC)      for RCWfield in RCWfieldList:     if RCWfield in ParcelFieldList:         print "Field", RCWfield, "found in", parcelsFC         arcpy.AddMessage("Field " + RCWfield + " found in " + parcelsFC)      else: # else the fieldname is not yet a field in the table, field will be added         print"Field", RCWfield, "NOT found in", parcelsFC         arcpy.AddMessage("\nField " + RCWfield + " NOT found in " + parcelsFC)         arcpy.AddField_management(parcelsFC, RCWfield, "DOUBLE")         print RCWfield, "created"         arcpy.AddMessage(RCWfield+" created/n")  #Select out each parcel record one by one and evalauate how many cluster buffers intersect with that parcel. #Update Parcel Attribute Table field three_mi with the # of buffers that intersect that parcel       for parcel in range(0,1092):     FID = "FID=%s" % (parcel)     arcpy.SelectLayerByAttribute_management(parcelsFL,"NEW_SELECTION",FID)     arcpy.SelectLayerByLocation_management(CbuffersFL,"INTERSECT",parcelsFL)     bufferCount = int(arcpy.GetCount_management(CbuffersFL).getOutput(0))     uc=arcpy.UpdateCursor(parcel)     for line in uc:         line.three_mi = bufferCount         uc.updateRow(line) #Actually changes the table values to buffer count     del line     del uc     #print "There are", bufferCount, "buffers that intersect with parcel FID #", FID     arcpy.SelectLayerByAttribute_management(parcelsFL,"CLEAR_SELECTION")


Error Statement:
Traceback (most recent call last):   File "P:\Environmental Division\The Nature Conservancy\TNC GIS Data\TNC GIS Projects\RCW\Code\ForLoop.py", line 68, in <module>     uc=arcpy.UpdateCursor(parcel)   File "C:\Program Files\ArcGIS\Desktop10.0\arcpy\arcpy\__init__.py", line 841, in UpdateCursor     return gp.updateCursor(*args)   File "C:\Program Files\ArcGIS\Desktop10.0\arcpy\arcpy\geoprocessing\_base.py", line 362, in updateCursor     self._gp.UpdateCursor(*gp_fixargs(args))) IOError: "0" does not exist


I'm not understanding why its saying IOError "0" does not exist. It's doing this on the very first record. The input value for this record should be 3. All fields that need to be populated currently have a value of 0. Field properties = double.

Thanks in advance
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
KerryAlley
Occasional Contributor
Sorry, I should have been more clear...
I was refering to line 68 (I think, based on the error message in your initial post) that was:
    uc=arcpy.UpdateCursor(parcel)

Because 'parcel' is an integer, the UpdateCursor wasn't being created.  It was just my guess that the data you wanted the cursor to access was your parcelsFL feature layer.  If that is the case, you can replace 'parcel' in your line that matches the one I pasted above with 'parcelsFL', like this:
    uc=arcpy.UpdateCursor(parcelsFL)

Regardless of what dataset you want to access with your cursor, you need to refer to it by its path which is a string.
Hope that clarifies what I was trying to say!

View solution in original post

0 Kudos
7 Replies
MichaelVolz
Esteemed Contributor
What is line 362?
0 Kudos
KerryAlley
Occasional Contributor
Your error is occurring because arcpy.UpdateCursor requires a string input (path to dataset), and your variable 'parcel' is an integer.
Try:
    uc=arcpy.UpdateCursor(parcelsFL)
0 Kudos
RachelAlbritton1
New Contributor III
mvolz47 - I do not have a line 362 in my code. My code only has 77 lines.

Kalley - I do have a direct path to the layer earlier in my code. Its just not shown here since the code is fairly long.
0 Kudos
RachelAlbritton1
New Contributor III
Here's my entire code


import arcpy, os

arcpy.env.workspace = "P:/Environmental Division/The Nature Conservancy/TNC GIS Data/TNC GIS Projects/RCW"
arcpy.env.overwriteOutput = True
outputWorkspace = "P:/Environmental Division/The Nature Conservancy/TNC GIS Data/TNC GIS Projects/RCW/RCW_Scratch"

def outName(input,post="_Output"):
    """Returns output name."""
    outName=os.path.basename(input).split(".")[0]+post
    return outName

#Criteria 1: Number of 3-mile RCW dispersal buffers that intersect parcel

#Create 3 mile buffers around each RCW cluster
Cluster = "RCW_Cluster.shp"
CBuffersFC = outputWorkspace+"/"+ outName(Cluster, "_3miBuff.shp")
bufferDist = "3 miles"
arcpy.Buffer_analysis(Cluster, CBuffersFC,bufferDist)

#Create Feature Layers from Feature Classes
parcelsFC = "ACUB_3mile.shp"
parcelsFL = outName(parcelsFC,"_Layer")
CbuffersFL = outName(CBuffersFC,"_Layer")

arcpy.MakeFeatureLayer_management(parcelsFC, parcelsFL)
arcpy.MakeFeatureLayer_management(CBuffersFC, CbuffersFL)

#From these buffers, select out all buffers that intersect with at least 1 ACUB parcel in priority zone 1
#Note - since RCW Clusters may move, be added, or taken away, this step should be part of the analysis and not preprocessing

arcpy.SelectLayerByLocation_management(CbuffersFL,"INTERSECT",parcelsFL)
parcelCount=int(arcpy.GetCount_management(CbuffersFL).getOutput(0))
print arcpy.GetMessages()
print "There are ",parcelCount," cluster buffers that intersect with at least 1 ACUB parcel. These parcels are being exported to a new feature class.\n"

#Copy Selected 3-Mile Cluster Buffer to a New Feature Class
FinalClusterBuff = outputWorkspace+"/"+ outName(CBuffersFC, "_Selected.shp")
arcpy.CopyFeatures_management(CbuffersFL,FinalClusterBuff)
print FinalClusterBuff, "created\n"
arcpy.AddMessage(FinalClusterBuff+" created")

#Before begining criteria analysis, code will check the attribute field names in the parcels table to ensure that attribute
#columns exist to hold analysis results for criteria's 1 - 5. If the field does not exist, one will be created.

RCWfieldList = ["three_mi","avg_gs","PGB_avg","one_25mi","pot_hab"]
ParcelFieldList=arcpy.ListFields(parcelsFC)
   
for RCWfield in RCWfieldList:
    if RCWfield in ParcelFieldList:
        print "Field", RCWfield, "found in", parcelsFC
        arcpy.AddMessage("Field " + RCWfield + " found in " + parcelsFC)

    else: # else the fieldname is not yet a field in the table, field will be added
        print"Field", RCWfield, "NOT found in", parcelsFC
        arcpy.AddMessage("\nField " + RCWfield + " NOT found in " + parcelsFC)
        arcpy.AddField_management(parcelsFC, RCWfield, "DOUBLE")
        print RCWfield, "created"
        arcpy.AddMessage(RCWfield+" created/n")

#Select out each parcel record one by one and evalauate how many cluster buffers intersect with that parcel.
#Update Parcel Attribute Table field three_mi with the # of buffers that intersect that parcel     
for parcel in range(0,1092):
    FID = "FID=%s" % (parcel)
    arcpy.SelectLayerByAttribute_management(parcelsFL,"NEW_SELECTION",FID)
    arcpy.SelectLayerByLocation_management(CbuffersFL,"INTERSECT",parcelsFL)
    bufferCount = int(arcpy.GetCount_management(CbuffersFL).getOutput(0))
    uc=arcpy.UpdateCursor(parcel)
    for line in uc:
        line.three_mi = bufferCount
        uc.updateRow(line) #Actually changes the table values to buffer count
    del line
    del uc
    #print "There are", bufferCount, "buffers that intersect with parcel FID #", FID
    arcpy.SelectLayerByAttribute_management(parcelsFL,"CLEAR_SELECTION")

[\CODE]
0 Kudos
KerryAlley
Occasional Contributor
Sorry, I should have been more clear...
I was refering to line 68 (I think, based on the error message in your initial post) that was:
    uc=arcpy.UpdateCursor(parcel)

Because 'parcel' is an integer, the UpdateCursor wasn't being created.  It was just my guess that the data you wanted the cursor to access was your parcelsFL feature layer.  If that is the case, you can replace 'parcel' in your line that matches the one I pasted above with 'parcelsFL', like this:
    uc=arcpy.UpdateCursor(parcelsFL)

Regardless of what dataset you want to access with your cursor, you need to refer to it by its path which is a string.
Hope that clarifies what I was trying to say!

View solution in original post

0 Kudos
RachelAlbritton1
New Contributor III
Kalley - Thank you for the clarification. That worked!
0 Kudos
CalebMackey1
Regular Contributor II
What is line 362?


This is coming from the ArcObjects conversion to a Python function.  You can actually open up the "base.py" script from the program files to view it.


def updateCursor(self, *args):
        """GP function UpdateCursor"""
        from ..arcobjects.arcobjectconversion import convertArcObjectToPythonObject
        return convertArcObjectToPythonObject(
                    self._gp.UpdateCursor(*gp_fixargs(args, True)))


This is how most of the arcpy tools are converted to python functions.  This is the update cursor ArcObject conversion into the geoprocessing wrapper.
0 Kudos