I have a search cursor that using a SQL query to match addresses and then returns the associated roll number with that address. However, some addresses do not match the roll number and then I believe the search cursor stops. Is there a bit of code I can throw in that will continue with the next address even if a match isn't found? I think an 'if' statement would work well, but I don't know what to write for it!
I'm having trouble generating this. My code is iterating through foldernames to get the address and querying a parcel layer.
I can post the code later, if you need an example.
import arcpy
import os
import re
import sys
import traceback
import collections
basedir = r"C:\Test"
fc = r"G:\ParcelsFixNames.shp"
field1 = "ADD1"
field2 = "STREETNAME"
try:
#find all foldernames in directory
for fn in os.listdir(basedir):
string = str(fn)
#split name at hyphen
if re.findall('-', fn):
#right side of hyphen is street address, leftside is street name
lhs, rhs = string.split('-')
street = str.lstrip(lhs)
street = str.replace(street,'.','')
street = str.rstrip(street)
street = str.upper(street)
add = str.lstrip(rhs)
expression3 = '"{field1}" = \'{add}\' AND "{field2}" LIKE \'%{street}%\''.format(field1=field1, add=add, field2=field2, street=street)
rows = arcpy.SearchCursor(fc, fields="STREETNAME; ARN; ADD1", where_clause=expression3)
for row in rows:
Roll = row.getValue("ARN")
newname = str(Roll)
newpath = os.path.join(basedir, newname)
#if the name exists already add _1 to end
if os.path.exists(newpath):
os.rename(os.path.join(basedir, fn),
os.path.join(basedir, newname + "_" + "1"))
else:
os.rename(os.path.join(basedir, fn),
os.path.join(basedir, newname))
else:
print add + " " + street + " " + "Already exists...passing"
continue
except:
print ("Error occurred")
tb = sys.exc_info()[2]
tbinfo = traceback.format_tb(tb)[0]
pymsg = "PYTHON ERRORS:\nTraceback Info:\n" + tbinfo + "\nError Info:\n " + \
str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n"
msgs = "GP ERRORS:\n" + arcpy.GetMessages(2 )+ "\n"
print (pymsg)
print (msgs)
2 Answers 2
Since you are using Arc 10.1, use the data access module to create your search cursors. As @Paul mentions, they are much better at releasing file locks, especially when using with
/as
:
fields = ["STREETNAME", "ARN", "ADD1"]
with arcpy.da.SearchCursor(mySitesTbl,fields,where) as rows:
try:
if rows.next() != ():
rows.reset()
for row in rows:
...
except StopIteration:
print('Empty Cursor')
-
Your syntax on fields should read
["STREETNAME", "ARN", "ADD1"]
. You also cannot access the length of a cursor object.Paul– Paul2013年07月19日 15:24:37 +00:00Commented Jul 19, 2013 at 15:24 -
So instead of using
len(rows) > 0
, try testing the search cursor for the empty tuple:if rows.next() != ():
or something similar.Jason Bellino– Jason Bellino2013年07月19日 15:39:17 +00:00Commented Jul 19, 2013 at 15:39 -
@Paul is correct, the search cursor object has no variable length. I have updated my answer to focus on using the data access module of Arc 10.1 and a better way to test for an empty cursor.Jason Bellino– Jason Bellino2013年07月19日 16:20:26 +00:00Commented Jul 19, 2013 at 16:20
-
2+1 Yep, that works. If OP wanted to pass over it instead of stopping (which I think he wants), it's a simple change to
pass
. Still, I've never had an issue with an empty cursor stopping my code.Paul– Paul2013年07月19日 16:23:45 +00:00Commented Jul 19, 2013 at 16:23 -
Upon further inverstigation I think an issue lies with the existing folder names, some contain suffixes such as "ST, DR, AVE, CRT" etc which do not match the street name's in the database... now I just gotta figure out how to remove the suffixes!GISHuman– GISHuman2013年07月19日 18:38:58 +00:00Commented Jul 19, 2013 at 18:38
maybe try a different cursor..
#arcpy.da.searchcursor is faster
f1, f2, f3 = "STREETNAME", "ARN", "ADD1"
x= 0
with arcpy.da.SearchCursor(fc, (f1, f2, f3), where_clause=expression3) as scur:
for row in scur:
x=x+len(row)
#if you're really curious about how many matches meet the expression3 you could
#do this - there's probably a more elegant way though!
print x
if x > 0:
with arcpy.da.SearchCursor(fc, (f1, f2, f3), where_clause=expression3) as scur:
for row in scur:
....
else:
-
sorry... i don't know how to post so the code looks right and hashes stay in. oh. and now i see Jason's answermwil– mwil2013年07月19日 14:52:11 +00:00Commented Jul 19, 2013 at 14:52
-
Instead of using three variables, you could just set f1 to a list. See my comment on Jason's answer.Paul– Paul2013年07月19日 15:25:35 +00:00Commented Jul 19, 2013 at 15:25
-
1@Paul are you sure? the output of arcpy.da.searchcursor is a tuple.. so we should be able to len() it.. i can't test at the momentmwil– mwil2013年07月19日 16:06:17 +00:00Commented Jul 19, 2013 at 16:06
-
It's actually the
rows.next()
method of the search cursor which returns a tupleJason Bellino– Jason Bellino2013年07月19日 16:11:28 +00:00Commented Jul 19, 2013 at 16:11 -
1@megwilliams, I'm sure. I'm looking at the results right now.
TypeError: object of type 'da.SearchCursor' has no len()
Paul– Paul2013年07月19日 16:18:28 +00:00Commented Jul 19, 2013 at 16:18
for row in rows
. What version of ArcMap are you using?