RuntimeError: 'in_table' is not a table or a featureclass

2555
8
Jump to solution
05-17-2021 07:36 AM
kad37_pns
New Contributor II

Hello!

I've been working on a script that will take a group of manually selected features and utilize UpdateCursor to update a field based on three other columns. As of right now, I'm programming it so that messages appear to provide proof of concept. The goal of this is to automate what was a field calculation process into a python add in button. 

So, I know that the correct layer is being selected and it will print out the said selected layer's OBJECTID. 

However, as soon as I get into updating the cursor, I'll receive an error message saying: 

line 29, in onClick
    with arcpy.da.UpdateCursor(sample,['block', 'sub_code', 'blockanno']) as blockanno:
RuntimeError: 'in_table' is not a table or a featureclass

Any suggestions on how to fix this or get around the error in order to run the nested if statements? 

Here is my current script: 

import arcpy
import pythonaddins

class ButtonClass1(object):
    """Implementation for Test2_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        ## if editing:
		## elif msg -- put on edit  and then exit
		mxd = arcpy.mapping.MapDocument('current')
		df = mxd.activeDataFrame
		Fields = ["block", "sub_code", "blockanno"]

		lyr = arcpy.mapping.ListLayers(mxd)[1]
		pythonaddins.MessageBox("layer is {}".format(lyr), "Message Box", 0)
		selected = ''
			
		sample = lyr.getSelectionSet()
		for row in sample:
			selected = selected + ', ' + str(row)
		
		pythonaddins.MessageBox("selected =" + str(selected), "Message Box", 0)
			
		with arcpy.da.UpdateCursor(sample,['block', 'sub_code', 'blockanno']) as blockanno:
			for row in blockanno:
				if row[1] != '0000' and row[1] != '0780':
					if row[0][0:3].isdigit():
						row[2] = str(row[0][0:3].lstrip('0'))
					elif row[0].isalpha():
						if row[0][0:2] == '00':
							row[2] = str(row[0][0:].strip('0'))
			# pythonaddins.MessageBox("blockanno is {}".format(row[2]), "Message Box", 0)
			blockanno.updateRow(row)
0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable

Your sample variable is just a list of objectid's (being returned from the getSelectionSet() method) and is not a table that is usable by the cursor.  I think that you will have to iterate over those ObjectID's, create a where clause for the cursor.  You can do them all at once, or one at a time. You will also have to pass in the featureclass that you are updating to where the 'sample' currently is.  Instead of the for row in sample line you got there, try something like this:

 

for oid in sample:
    whereclause = f'''OBJECTID = {oid}'''
    with arcpy.da.UpdateCursor('YOUR FC HERE', ['block', 'sub_code', 'blockanno'], whereclause) as uCur:
        for row in uCur:
            ...

 

 PS, Id also change the blockanno cursor to uCur or something to differentiate it from the blockanno field.

View solution in original post

8 Replies
by Anonymous User
Not applicable

Your sample variable is just a list of objectid's (being returned from the getSelectionSet() method) and is not a table that is usable by the cursor.  I think that you will have to iterate over those ObjectID's, create a where clause for the cursor.  You can do them all at once, or one at a time. You will also have to pass in the featureclass that you are updating to where the 'sample' currently is.  Instead of the for row in sample line you got there, try something like this:

 

for oid in sample:
    whereclause = f'''OBJECTID = {oid}'''
    with arcpy.da.UpdateCursor('YOUR FC HERE', ['block', 'sub_code', 'blockanno'], whereclause) as uCur:
        for row in uCur:
            ...

 

 PS, Id also change the blockanno cursor to uCur or something to differentiate it from the blockanno field.

kad37_pns
New Contributor II

Could you explain a bit more on what the line: 

 whereclause = f'''OBJECTID = {oid}'''

Is supposed to accomplish? I've been scratching my head over that. Thank you. 

0 Kudos
by Anonymous User
Not applicable

Its creating a sql query string to select the feature by matching the OBJECTID to the oid.  It can also be written as 'OBJECTID = {}'.format(oid) or like 'OBJECTID = ' + str(oid).  It is then used in the cursor to filter the selection to the matching feature(s).

0 Kudos
DavidPike
MVP Frequent Contributor

I'm with Jeff on this.

0 Kudos
Tomasz_Tarchalski
New Contributor III

not sure, but try just calling the layer by its name. as ther is selection, update cursor will work on selection. So replace  line:

 

sample = lyr.getSelectionSet()

 

with line

 

sample = lyr.name

 

 

0 Kudos
kad37_pns
New Contributor II

Yeah, unfortunately all that produces is the actual name of the layer, not what's within the layer which is what I'm trying to calculate from. Thanks, though!

0 Kudos
by Anonymous User
Not applicable

You may be able to just use the lyr variable in place of 'sample' in your updatecursor since it's pointing to the featureclass, replacing the 'your FC here' from my example above, and maybe skipping the iteration over the 'sample' list of objectids.

0 Kudos
kad37_pns
New Contributor II

Discovered that my issue was in how I was formatting my rows. Below is a piece of code that worked for me: 

with arcpy.da.UpdateCursor(lyr, Fields) as uCur:
			print("got here")
			for row in uCur:
				row[4] = self.block_anno_calc(row[0], row[1], row[2], row[3])

 

 

Thanks for the help, y'all! Made some good headway on this project.

0 Kudos