3

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)
7
  • Posting the code you are working with is always helpful to get things started. Jul 19, 2013 at 13:37
  • @Jason added... it's involved...
    – GISHuman
    Jul 19, 2013 at 13:42
  • Which bit of the code is the one that fails when a match is not found? I'm a little confused as to what you mean by the address not matching the roll number...I assume you are comparing the roll number associated with an address in your feature to another roll number value taken from somewhere else? Jul 19, 2013 at 13:58
  • If there are no features returned by a search cursor, it should pass right over your for row in rows. What version of ArcMap are you using?
    – Paul
    Jul 19, 2013 at 14:00
  • @Paul 10.1 I'm running this as a standalone script in pyscripter
    – GISHuman
    Jul 19, 2013 at 14:12

2 Answers 2

4

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')
5
  • Your syntax on fields should read ["STREETNAME", "ARN", "ADD1"]. You also cannot access the length of a cursor object.
    – Paul
    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. 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. 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
    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
    Jul 19, 2013 at 18:38
0

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:  
5
  • sorry... i don't know how to post so the code looks right and hashes stay in. oh. and now i see Jason's answer
    – mwil
    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
    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 moment
    – mwil
    Jul 19, 2013 at 16:06
  • It's actually the rows.next() method of the search cursor which returns a tuple 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
    Jul 19, 2013 at 16:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.