Creating a Function with an Update Cursor

374
8
Jump to solution
04-08-2021 02:52 PM
TatjanaScagliotti
New Contributor II

I have an update cursor that updates rows of a feature class on AGOL. The code below works.

with arcpy.da.UpdateCursor (fc, ['OBJECTID_1', 'Wk4_March29April1_ACTIV','Wk4_HRS', 'Wk5_April5April8_ACTIV','Wk5_HRS'], "Wk4_March29April1_ACTIV LIKE '%Planned%'") as cursor:
    for row in cursor:
        row[3] = row[1]
        row[4] = row[2]
        row[1] = None
        row[2] = None
        cursor.updateRow(row)

I'm now trying to turn this code into a function so I don't have to keep hard coding the values. However, the function I've made isn't working when I call it and pass in the variables I want to use. The code below is the function.

def weekly_update(week_a, hours_a, week_b, hours_b):
     with arcpy.da.UpdateCursor (fc, ['OBJECTID_1', 'week_a','hours_a', 'week_b','hours_b'], "week_a LIKE '%Planned%'") as cursor:
        for row in cursor:
            row[3] = row[1]
            row[4] = row[2]
            row[1] = None
            row[2] = None
            cursor.updateRow(row)

#call the function and pass in the variables 

weekly_update("Wk25_Oct12Oct15_ACTIV", "Wk25_HRS", "Wk26_Oct19Oct22_ACTIV", "Wk26_HRS")

 

This is the error I keep getting 

RuntimeError: A column was specified that does not exist. [week_a]

Any suggestions would be great. Thanks! 

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
RandyBurton
MVP Regular Contributor

@JoeBorgioneand @JeffK  offer good solutions.  But you also need to use the  proper form in your query since 'week_a' is a variable name and not the actual field name.

 

def weekly_update(week_a, hours_a, week_b, hours_b):
     with arcpy.da.UpdateCursor (fc, ['OBJECTID_1', week_a,hours_a, week_b,hours_b], "{} LIKE '%Planned%'".format(week_a)) as cursor:

 

Or, with Jeff's idea:

fldList = ["Wk25_Oct12Oct15_ACTIV", "Wk25_HRS", "Wk26_Oct19Oct22_ACTIV", "Wk26_HRS"]

def weekly_update(fldList):
     with arcpy.da.UpdateCursor (fc, fldList, "{} LIKE '%Planned%'".format(fldList[0])) as cursor:

   ....

View solution in original post

8 Replies
JoeBorgione
MVP Esteemed Contributor
def weekly_update(week_a, hours_a, week_b, hours_b):
     with arcpy.da.UpdateCursor (fc, ['OBJECTID_1', 'week_a','hours_a', 'week_b','hours_b']

Try removing the quotes around your parameter-variable names. When you enclose them like that the cursor is looking for a field of those names instead of the value of the variables.

can't wait to retire....
TatjanaScagliotti
New Contributor II

Unfortunately, that doesn't work.

0 Kudos
JeffK
by
Occasional Contributor III

Joe is correct. ...An alternative that might help keep variables and parameter assignments from getting tangled is to just pass a list of the fields like:

 

fldList = ["Wk25_Oct12Oct15_ACTIV", "Wk25_HRS", "Wk26_Oct19Oct22_ACTIV", "Wk26_HRS"]

def weekly_update(fldList):
     with arcpy.da.UpdateCursor (fc, fldList, "{} LIKE '%Planned%'".format(fldList[0])) as cursor:
        for row in cursor:
            row[3] = row[1]
            row[4] = row[2]
            row[1] = None
            row[2] = None
            cursor.updateRow(row)

#call the function and pass in the variables 

weekly_update(fldList)

 

 

BlakeTerhune
MVP Regular Contributor

This is a good solution. Just be aware @TatjanaScagliotti that if you don't pass the right number of fields, the field assignment will error out. You could validate the fldList argument before opening the cursor to make sure it's got four items.

assert len(fldList) == 4, "fldList must have exactly 4 field names; like week_a, hours_a, week_b, hours_b"
TatjanaScagliotti
New Contributor II

Thank you, I like the idea of using a list and having an assert statement.

0 Kudos
RandyBurton
MVP Regular Contributor

@JoeBorgioneand @JeffK  offer good solutions.  But you also need to use the  proper form in your query since 'week_a' is a variable name and not the actual field name.

 

def weekly_update(week_a, hours_a, week_b, hours_b):
     with arcpy.da.UpdateCursor (fc, ['OBJECTID_1', week_a,hours_a, week_b,hours_b], "{} LIKE '%Planned%'".format(week_a)) as cursor:

 

Or, with Jeff's idea:

fldList = ["Wk25_Oct12Oct15_ACTIV", "Wk25_HRS", "Wk26_Oct19Oct22_ACTIV", "Wk26_HRS"]

def weekly_update(fldList):
     with arcpy.da.UpdateCursor (fc, fldList, "{} LIKE '%Planned%'".format(fldList[0])) as cursor:

   ....

View solution in original post

TatjanaScagliotti
New Contributor II

Thank you,  the .format() is exactly what I needed.

"{} LIKE '%Planned%'".format(fldList[0])

 

0 Kudos
JoeBorgione
MVP Esteemed Contributor

 

(fc, ['OBJECTID_1', week_a, hours_a, week_b, hours_b], "week_a LIKE '%Planned%'")

 

Then it must be the reference to week_a in your selection statement that's bombing it.  (I didn't notice that).

If you are using python 3.x I suggest using an f string like this:

(fc, ['OBJECTID_1', week_a, hours_a, week_b, hours_b], f'{week_a} LIKE "%Planned%"')

of if you are using python 2.x you'll need to use the format() method:

(fc, ['OBJECTID_1', week_a, hours_a, week_b, hours_b], '{} LIKE "%Planned%"'.format(week_a)

(Of course these are untested, but I think that'll get you going...)

 

can't wait to retire....