4

How can I use arcpy to check if a search cursor returns anything and then do something based on the answer. So far I have this and it recognizes the positive - i.e. when i pass the query for 001 it gets the value, but when I substitute a bad value, the script does not print "No Search Cursor"

import arcpy

table = "A_Table"
query = "\"FeatureID\" = '001'"  
theseRows = arcpy.SearchCursor(table, query)

for row in theseRows:
    if theseRows:
        print(row.getValue("FeatureID"))
    else:
        print "No Search Cursor"
detroit_hc
  • 807
  • 1
  • 9
  • 20
  • You're trying to do a CountFeatures sort of thing? you should be able to do if not theseRows: which will return true if the list (the cursor) is empty. – Michael Stimson Sep 10 '14 at 23:24
  • if I feed the query a junk value, it is still returning a search cursor object... which tells me I need a method to check and see if the cursor is returning anything at all ,not just that it's been established. – detroit_hc Sep 10 '14 at 23:33
  • if not theseRows: should return false if there's nothing in the list but that might be only for arcpy.da.SearchCursor. I always do a count before declaring a cursor as count is lightweight and non-locking but cursors lock (shared) and leave junk that needs to be cleaned up. – Michael Stimson Sep 10 '14 at 23:41

4 Answers4

8

Just a tip - if you're using ArcGIS 10.1 or higher, you should look at the arcpy.da version of search cursor, as it's much faster. Also, consider using the with... notation used in the example on that page, as it's a cleaner way to manage the cursor.

with arcpy.da.SearchCursor(fc, fields) as cursor:
    for row in cursor:
        print('{0}, {1}, {2}'.format(row[0], row[1], row[2]))

But rather than using a cursor, perhaps a better way to check if the query returns anything is shown in the Make Query Table example 2:

# Make Query Table...
arcpy.MakeQueryTable_management(tableList, lyrName,"USE_KEY_FIELDS", keyField, fieldList, whereClause)

# Print the total rows
print arcpy.GetCount_management(lyrName)

That is, create a query layer from the table and its where clause, then use GetCount to see whether it contains any records.

(PS I just tried @polygeo's suggestion of MakeTableView and it's a bit simpler - so you could run that, then GetCount)

Stephen Lead
  • 21,119
  • 17
  • 113
  • 240
  • 1
    +1 for GetCount but I think the preceding MakeQueryTable step is (often) unnecessary. If you can open a SearchCursor on it then I think you can usually/always use GetCount. – PolyGeo Sep 11 '14 at 00:02
  • 1
    @PolyGeo but without making a query table on it, how will you run the query featureID = 001? GetCount will return the total count of the table, not just the desired rows – Stephen Lead Sep 11 '14 at 00:08
  • 1
    That's a fair point - MakeFeatureLayer and MakeTableView are two other possible ways that take a where_clause. – PolyGeo Sep 11 '14 at 00:18
  • Perhaps though if you insist on skipping the count you could set a boolean before the iteration to false, change to true during iteration and then test afterward - if true then a row has been returned (at least 1) if it's false then no rows were returned... an empty cursor will not enter an iteration. – Michael Stimson Sep 11 '14 at 00:23
3

An else on a for loop doesn't work like that.

for row in theseRows:
    # do interesting work
else:
    print "No rows found"

will always print "No rows found" as long as no break was encountered in the for loop. A For on an empty list is still a non-breaking For.

Something like this would work:

flag = False
for row in theseRows:
    flag = True
    # do interesting work

if not flag:
    print "No rows found"
detroit_hc
  • 807
  • 1
  • 9
  • 20
Mark Denil
  • 54
  • 1
2

You can use the else block on a for loop:

theseRows = arcpy.SearchCursor(table, query)

for row in theseRows:
    # do interesting work
else:
    print "No rows found"
Jason Scheirer
  • 18,002
  • 2
  • 53
  • 72
  • will always print "No rows found" as long as no break was encountered in the for loop. A For on an empty list is still a non-breaking For. – Below the Radar Jul 15 '16 at 18:40
2

Simple method (used arcpy.da version of cursors in 10.4, works in Pro too)

for row in cur:
    break
else:
    print("Cursor is empty")

or :

try:
    cur.next()
except: #I don't remember the exception but its easy to check
    print("Cursor is empty")
Mojimi
  • 201
  • 1
  • 10