UpdateCursor 'skip optional parameters' not working...

1472
9
08-06-2012 01:38 PM
AbbyFlory
New Contributor
Hi,

I'm using Python code in PyScripter with ArcGIS 10.0 to step through rows using an UpdateCursor, however I cannot get it to skip over optional parameters. 

UpdateCursor takes: UpdateCursor (dataset, {where_clause}, {spatial_reference}, {fields}, {sort_fields}).  I am interested in setting the 'dataset' (required) and 'fields' (optional) only, and I have tried the following three methods as suggested on the ArcGIS 10.0 help site:

cur1 = arcpy.UpdateCursor("InputLyr","","",["UnqRecordI","UnqWellLoc"])
cur1 = arcpy.UpdateCursor("InputLyr","#","#",["UnqRecordI","UnqWellLoc"])
cur1 = arcpy.UpdateCursor("InputLyr",fields=["UnqRecordI","UnqWellLoc"])


All three result in errors: "Object: Error in parsing arguments for UpdateCursor" for the first two, and "UpdateCursor() got an unexpected keyword argument 'fields'" for the third. 

I cannot for the life of me figure out what could be wrong with the parsing.  Your help/suggestions would be greatly appreciated!

Thanks in advance!
Tags (2)
0 Kudos
9 Replies
JakeSkinner
Esri Esteemed Contributor
Hi Abby,

You will need to remove the brackets around the fields parameter, only use one set of quotation marks, and separate each field with a semicolon.  Ex:

cur1 = arcpy.UpdateCursor("InputLyr", "", "", "UnqRecordI; UnqWellLoc")


Another example can be seen in the Help for the SearchCursor:

http://resources.arcgis.com/en/help/main/10.1/index.html#/SearchCursor/018v00000050000000/
0 Kudos
AbbyFlory
New Contributor
Thanks Jake!  Two additional questions, if you don't mind...

1) Is there a way to check the number of fields the cursor is using?  When I use the following code after setting the cursor, it returns the entire feature class field count instead of being limited to only the fields I listed in the cursor:

desc = arcpy.Describe("InputLyr")
FieldInfo = desc.fieldInfo
print "Field Count =",FieldInfo.count


2) Is there a way to include a changing variable in the fields list for the cursor?  For example,

cur1 = arcpy.UpdateCursor("InputLyr","","","UnqRecordI; UnqWellLoc; ChangingVariableHere")


For instance, would this be correct(?):

a = 1
ChangingField = "CmpltFlg_" + str(a)
cur1 = arcpy.UpdateCursor("InputLyr","","","UnqRecordI; UnqWellLoc;",ChangingField,"")


Thanks for your help!!
0 Kudos
JakeSkinner
Esri Esteemed Contributor
1)  The fields set within the cursor will only apply when iterating through the cursor object.  To limit the fields you will need to set this within the MakeFeatureLayer_management function.  Ex:

fc = "Hospitals"
layer = "temp_layer"

arcpy.MakeFeatureLayer_management(fc, layer, "", "", "STATE_NM; LINK_ID")
desc = arcpy.Describe(layer)
fieldInfo = desc.fieldInfo

print "Field Count =", fieldInfo.count



2)  Yes, this should be possible.  Try the following:

a = 1
ChangingField = "CmpltFlg_" + str(a)
cur1 = arcpy.UpdateCursor("InputLyr","","","UnqRecordI; UnqWellLoc;" + ChangingField)
0 Kudos
AbbyFlory
New Contributor
Awesome!  Thanks so much!  I'm interested in limiting the fields in order to make my code run more efficiently.  Is this better to do in MakeFeatureLayer versus UpdateCursor?  Also, if I decided to set fields in the UpdateCursor and not in the MakeFeatureLayer, is there a way to check that it's only using/reading the fields I've specified?  For instance, the fieldInfo.count reads fields in a Layer, but is there a similar feature within a cursor so I can make sure that it's only reading my specified fields?
0 Kudos
JakeSkinner
Esri Esteemed Contributor
A cursor is used to iterate through a table or feature class.  If you want to describe a feature class, this should not be executed within cursor, because it will describe the feature class for each row within the cursor (which would be overkill).  If there are 10,000 rows, you would be describing the feature class 10,000 times.

If you want to verify that the UpdateCursor is only using the fields you specified within the cursor, try printing a field that you did not specify.  For example:

rows = arcpy.UpdateCursor(fc, "", "", "FCC; LOC_ID")
for row in rows:
    print row.NAME

del rows, row


I did not specify the field 'NAME' for my cursor, but this field does exist.  When I print the values for this field I receive 'None' rather the field value.
0 Kudos
AbbyFlory
New Contributor
Thanks!  When I use MakeFeatureLayer and include field restrictions, however, it does not recognize any of my fields.  In the code below, all of the "print FieldInfo.getFieldName()" lines return the correct fields/names.  When I try to access any of these fields within the cursor though, it throws an error: "Row: Field FID does not exist" (or "Row: Field ___ does not exist" - for any of the other fields it should be reading).  Any suggestions?

# Imports...
import time
import Functions
import arcpy
import sys
import traceback
from arcpy import env
from arcpy.sa import *

Input = "C:/AF_WorkingFiles/AgHealth_Iowa/Databases/Shapes/NitrateWells_LandCover/Test_10Locs.shp"
arcpy.MakeFeatureLayer_management(Input,"InputLyr","","","FID; Shape; OBJECTID; UnqRecordI; UnqWellLoc; Flg90_500")

# List land-cover rasters...
L1 = ["LC85","LC90","LC92","LC00","LC02","LC06","LC09"]
for item in L1:

    # Environments...
    env.workspace = "C:/AF_WorkingFiles/AgHealth_Iowa/Databases/TempData.mdb"
    env.overwriteOutput = "True"
    env.snapRaster = "'C:/AF_WorkingFiles/AgHealth_Iowa/Databases/AHS_SpatialData.mdb/" + item + "'"
    env.cellSize = "'C:/AF_WorkingFiles/AgHealth_Iowa/Databases/AHS_SpatialData.mdb/" + item + "'"
    env.extent = "'C:/AF_WorkingFiles/AgHealth_Iowa/Databases/AHS_SpatialData.mdb/" + item + "'"
    env.maintainSpatialIndex = False
    env.scratchWorkspace = "C:/AF_WorkingFiles/AgHealth_Iowa/Databases/Scratch"
    LC_Raster = item

    # List buffer sizes...
    L2 = ["500","1000","2000","10000"]
    for item in L2:

        # For each raster/buffer combo, do the following:
        BuffSize = item
        Dist = item + " Meters"
        a = 0

        cur1 = arcpy.UpdateCursor("InputLyr")
        rowCount = arcpy.GetCount_management("InputLyr")
        print "Row Count =",rowCount

        desc = arcpy.Describe("InputLyr")
        FieldInfo = desc.fieldInfo
        print "Field Count =",FieldInfo.count
        print "Field 1 =",FieldInfo.getFieldName(0)
        print "Field 2 =",FieldInfo.getFieldName(1)
        print "Field 3 =",FieldInfo.getFieldName(2)
        print "Field 4 =",FieldInfo.getFieldName(3)
        print "Field 5 =",FieldInfo.getFieldName(4)
        print "Field 6 =",FieldInfo.getFieldName(5)

        for row in cur1:
            a = a+1
            print row.FID

del cur1, row
0 Kudos
JakeSkinner
Esri Esteemed Contributor
I was incorrect before, the 'field_info' parameter for the MakeFeatureLayer_management function will hide fields.  See the description of this parameter here.  This is why you cannot find any fields when you iterate through the feature layer using a cursor.

However, this doesn't explain why the 'desc.fieldInfo.count' method returns the number of fields that you specify to be hidden, and not the ones that are visible.  This may be a bug.
0 Kudos
AbbyFlory
New Contributor
Huh, yea that's really interesting.  The icon by your name means you work for ESRI, right?  Can you report this bug or should I?

Abby
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Hi Abby,

It would be best for you to report the bug to Tech Support.  They will confirm whether it's a bug, and provide any workarounds.
0 Kudos