arcpy.da.UpdateCursor too few parameters

2972
11
Jump to solution
03-16-2016 10:40 AM
JustinWolff
Occasional Contributor

I'm running ArcGIS 10.3 and have a geodatabase with multiple feature datasets each containing multiple feature classes.  Each feature class has multiple string type fields containing <Null> values.  I want to change the <Null> values to "TBD" (without the quotation marks).

I feel I'm very close, but at 'for row in cursor:' I'm receiving the error "Too few parameters.  Expected 1."  I guess the cursor isn't actually returning any rows at all?  Below is what I currently have; I haven't added any documentation or messaging yet.  Any help would be greatly appreciated.

import arcpy
from arcpy import env
import os

#Set variables
inputgdb = sys.argv[1]
nullCount = 0

#Set workspace
arcpy.env.workspace = inputgdb

#Populate Nulls with TBD
datasetList = arcpy.ListDatasets(feature_type = 'feature')
datasetList = [''] + datasetList if datasetList is not None else []
for dataset in datasetList:
    env.workspace = inputgdb + "\\" + dataset
    dataset = dataset + "\\"
    fcList = arcpy.ListFeatureClasses()
    for fc in fcList:
        fc = fc +"\\"
        fieldList = arcpy.ListFields(fc,["String"])
        for field in fieldList:
            with arcpy.da.UpdateCursor (fc, 'fieldList') as cursor:
                for row in cursor:
                    if row[0] == None:
                        row[0] = 'TBD'
                        cursor.updateRow(row)
Tags (1)
0 Kudos
1 Solution

Accepted Solutions
DarrenWiens2
MVP Honored Contributor

Ah, I assumed ListFields returned a list of field names, but it returns field objects. See Joshua's answer or the final example here for creating a list of field names from ListFields.

View solution in original post

11 Replies
WesMiller
Regular Contributor III

Through in some print statements

I would recommend:

print datasetList

print fc

print fieldList

after each has been assigned I don't think you are getting the values you are expecting

DarrenWiens2
MVP Honored Contributor

You create a list called fieldList, but then try to call a single field (string) called 'fieldList'. Remove the quotes to access the variable fieldList, rather than the string 'fieldList'.

edit: actually, if you mean to loop through individual fields in fieldList, then you should direct the cursor to look for field (no quotes).

edit 2: rather than cursoring through your feature classes for each string field, you should cursor through each feature class once and inspect the values in row.

WesMiller
Regular Contributor III

Darren,

I think he is trying to get field type string

field_names = [f.name for f in arcpy.ListFields(fc,'','String')]

Edit:

Sorry just looked at your edit 2

0 Kudos
JustinWolff
Occasional Contributor

Darren and Wes,

Thanks for the suggestions.  I did add some messaging and it is at least returning the feature datasets, feature classes and fields as I was anticipating.

If I understand Darren's edit 2, I don't need to cursor through a list of fields, just the list of feature classes?

Thanks again.

0 Kudos
DarrenWiens2
MVP Honored Contributor

Right, I believe creating cursors is an expensive operation, so the fewer the better.

for dataset in datasetList:
    env.workspace = inputgdb + "\\" + dataset
    dataset = dataset + "\\"
    fcList = arcpy.ListFeatureClasses()
    for fc in fcList:
        fc = fc +"\\"
        fieldList = arcpy.ListFields(fc,["String"])
        with arcpy.da.UpdateCursor (fc, fieldList) as cursor:
            for row in cursor: # for each row in the feature class
                 for i in len(row): # for each value in row (i.e. field values)
                    if row == None:
                        row = 'TBD'
                 cursor.updateRow(row)
0 Kudos
JustinWolff
Occasional Contributor

I think I'm getting closer, but it does not like the fieldList in cursor.

error_field_names_string.png

import arcpy
from arcpy import env
import os
#Set variables
inputgdb = sys.argv[1]
nullCount = 0
#Set workspace
arcpy.env.workspace = inputgdb
#Populate Nulls with TBD
datasetList = arcpy.ListDatasets(feature_type = 'feature')
datasetList = [''] + datasetList if datasetList is not None else []
print "Getting Feature Datasets..."
arcpy.AddMessage ("Getting Feature Datasets...")
print datasetList
arcpy.AddMessage (datasetList)
for dataset in datasetList:
    env.workspace = inputgdb + "\\" + dataset
    dataset = dataset + "\\"
    fcList = arcpy.ListFeatureClasses()
    print "Getting Feature Classes..."
    arcpy.AddMessage ("Getting Feature Classes...")
    print fcList
    arcpy.AddMessage (fcList)
    for fc in fcList:
        fc = fc +"\\"
        fieldList = arcpy.ListFields(fc,["String"])
        with arcpy.da.UpdateCursor (fc, fieldList) as cursor:
            for row in cursor: #for each row in the feature class
                for i in len(row): #for each value in row (i.e., field values)
                    if row == None:
                        row = 'TBD'
                cursor.updateRow(row)
                print "Updating value..."
                arcpy.AddMessage ("Updating value...")
                print fieldList
                arcpy.AddMessage (fieldList)
0 Kudos
DarrenWiens2
MVP Honored Contributor

Ah, I assumed ListFields returned a list of field names, but it returns field objects. See Joshua's answer or the final example here for creating a list of field names from ListFields.

JustinWolff
Occasional Contributor

Thank you so much to everyone; it's working.

import arcpy
from arcpy import env
import os
#Set variables
inputgdb = sys.argv[1]
nullCount = 0
#Set workspace
arcpy.env.workspace = inputgdb
#Populate Nulls with TBD
datasetList = arcpy.ListDatasets(feature_type = 'feature')
datasetList = [''] + datasetList if datasetList is not None else []
print "Getting Feature Datasets..."
arcpy.AddMessage ("Getting Feature Datasets...")
print datasetList
arcpy.AddMessage (datasetList)
for dataset in datasetList:
    env.workspace = inputgdb + "\\" + dataset
    dataset = dataset + "\\"
    fcList = arcpy.ListFeatureClasses()
    print "Getting Feature Classes..."
    arcpy.AddMessage ("Getting Feature Classes...")
    print fcList
    arcpy.AddMessage (fcList)
    for fc in fcList:
        fc = fc +"\\"
        fieldList = [f.name for f in arcpy.ListFields(fc, "*", "STRING")]
        with arcpy.da.UpdateCursor (fc, fieldList) as cursor:
            for row in cursor:
                row = [(fld if fld is not None else 'TBD') for fld in row]
                cursor.updateRow(row)
                print "Updating value..."
                arcpy.AddMessage ("Updating value...")
                print fieldList
                arcpy.AddMessage (fieldList)
JoshuaBixby
MVP Esteemed Contributor

Correct.  As a side note, you should really consider using the os.path module to create file system paths (like feature classes in feature datasets).

Starting at the fieldList statement towards the bottom of your script:

fieldList = [f.name for f in arcpy.ListFields(fc, "*", "STRING")]
with arcpy.da.UpdateCursor (fc, fieldList) as cursor:
    for row in cursor:
        row = [(fld if fld is not None else 'TBD') for fld in row]
        # row = [(fld if fld else 'TBD') for fld in row] # this would capture empty strings too and not just NULL
        cursor.updateRow(row)