ERROR 000358: Invalid expression with gp.SelectLayerByAttribute

930 views
Skip to first unread message

steve....@gov.bc.ca

unread,
Feb 11, 2011, 12:12:30 PM2/11/11
to geop...@googlegroups.com
Buffering roads. Too many to do all at once so I'm breaking them into groups using forest district boundaries.
Iterating through the districts file, selecting a district, then intersecting to select a group of roads, buffering and dissolving, and then appending to output files.
Getting an error on the second time through the loop to do with the selection of the district.
The first iteration works fine, the second gives me the "invalid expression" error.
I don't understand why it should work the first time through (creates the buffers and saves them fine) and then it decides it doesn't like
the expression to select the district anymore?
 
My code (no formatting, problem line is highlighted in yellow):
 
wss = gp.searchcursor(fdistricts)
ws = wss.Next()
fdistrictscount = 1
while ws:
districtID = ws.getvalue('ORG_UNIT')
# Get the unique ID # for the current woodlot.
print 'Iteration # '+str(fdistrictscount)
print ' selecting the forest district'
selectFdistrict = gp.SelectLayerByAttribute(fdistricts, "NEW_SELECTION", '\"ORG_UNIT\" = \'' + str(districtID) + '\'')
print ' selecting all major roads near woodlots within the '+districtID+' district'
majorRoadSelect = gp.SelectLayerByLocation(majorRoads, "INTERSECT", fdistricts)
# Create the buffer polygons around the roads.
print ' creating buffer around the selected major roads'
bufferPoly = gp.Buffer_Analysis(majorRoadSelect, proj_main+tempRoadBuff, "1 Kilometers", "FULL", "ROUND")
print ' dissolving buffer lines based on ROAD_NAME_ID'
tempDissolve = gp.dissolve(bufferPoly, proj_main+tempBuffDissolve, "ROAD_NAM_5")
if fdistrictscount == 1:
print ' saving the buffer of the selected major roads as a new shapefile'
gp.CopyFeatures(bufferPoly, proj_main+output1)
gp.MakeFeatureLayer(proj_main+output1+'.shp', output)
print ' saving the dissolve of the buffers as a new shapefile'
gp.CopyFeatures(tempDissolve, proj_main+output2)
gp.MakeFeatureLayer(proj_main+output2+'.shp', dissolve)
# If not the first iteration then don't create a new road select layer, append to the existing road select layer.
else:
print ' appending the buffer information to the output file'
gp.append(bufferPoly, output, "NO_TEST")
print ' appending the dissolve information to the output file'
gp.append(tempDissolve, dissolve, "NO_TEST")
# Step up the count and return for the next record in the forest district layer and select the
# next group of woodlots.
fdistrictscount = fdistrictscount + 1
print ' Moving on'
print ' '
ws = wss.Next()

tarkenton

unread,
Feb 11, 2011, 2:10:35 PM2/11/11
to geop...@googlegroups.com
Hey Steve

Took me a couple minutes to get to the bottom of this one!

I think the problem has to do with a lack of feature layer.  Remember you cannot select directly from feature class.  You need to first create a feature layer which wraps the feature class.  Then make your selection from the featurelayer.

So a simplified version of your code above might look like this:

import arcgisscripting
gp = arcgisscripting.create(9.3)

# define the feature class you want to iterate through
fdistricts = r'Database Connections\LRDW4Scripts.sde\WHSE_ADMIN_BOUNDARIES.FADM_DISTRICT'
fdistrictsLyr = 'fdistLyr'
# wrapping the feature class with a feature layer
gp.makefeatureLayer_management(fdistricts, fdistrictsLyr)
#creating search cursor
wss = gp.searchcursor(fdistricts)
# calling the first record in the cursor
ws = wss.Next()
fdistrictscount = 1
while ws:
    # get the district id for the current district row and print it
    districtID = ws.getvalue('ORG_UNIT')
    print "District id is:" + districtID
    # selecting the polygon associated with districtID in the layer fdistrictsLyr
    selectFdistrict = gp.SelectLayerByAttribute(fdistrictsLyr, "NEW_SELECTION", '\"ORG_UNIT\" = \'' + str(districtID) + '\'')
    # getting the number or records currently selected.
    cntObj = gp.getcount_management(fdistrictsLyr)
    print 'records selected:', str(cntObj.getoutput(0))
    fdistrictscount = fdistrictscount + 1
    print ' '
    ws = wss.Next()

Basically the only change was the insertion of the line prior to the start of the loop that creates the feature layer on the forest district data set.
gp.makefeatureLayer_management(fdistricts, fdistrictsLyr)

And then the line that is selecting the specific forest district selects from the layer (fdistrictsLyr) instead of the feature class (fdistricts).

Does this make sense.  Let me know

Cheers

Kevin



steve....@gov.bc.ca

unread,
Feb 11, 2011, 2:17:08 PM2/11/11
to geop...@googlegroups.com
Thanks Fran - I have the file converted to  a feature layer earlier in my code so I'm not sure that thsi will help, hwoever I'll move the step to the start of the loop. I've attached the entire Python script file for your review.
K:WorkareaHLS - Water ProtectionsbaumberPython ScriptsRoadsAndWoodlots_buffer.py

steve....@gov.bc.ca

unread,
Feb 11, 2011, 2:37:41 PM2/11/11
to geop...@googlegroups.com
Placement of the feature class to layer conversion is not the issue - still crashes on the second iteration.

Fran Tarkington

unread,
Feb 11, 2011, 2:59:52 PM2/11/11
to geop...@googlegroups.com
Just commented out all the lines that actually do anything except those specific to looping through the forest districts, and it seems to work for me.  Attached the trimmed down copy to this email.  Does it work for you?  Can you forward what the actual error message looks like!


On Fri, Feb 11, 2011 at 11:37 AM, <steve....@gov.bc.ca> wrote:
Placement of the feature class to layer conversion is not the issue - still crashes on the second iteration.

--
You received this message because you are subscribed to the Google Groups "Python - ARCGIS geoprocessing" group.
To post to this group, send email to geop...@googlegroups.com.
To unsubscribe from this group, send email to geopython+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/geopython?hl=en.

baumberScript.py

steve....@gov.bc.ca

unread,
Feb 11, 2011, 3:07:08 PM2/11/11
to geop...@googlegroups.com
Ya, that's what gets me is that I've just used this loop to select other features (woodlots and then roads near woodlots in my case) according to the forest district boundaries - it's a quick way of iterating a process that's too big to do all at once. And it works there.
 
The error message I get is:

Traceback (most recent call last):

File "K:\HLS - Water Protection\sbaumber\Python Scripts\RoadsAndWoodlots_buffer.py", line 98, in <module>

selectFdistrict = gp.SelectLayerByAttribute(fdistricts, "NEW_SELECTION", '\"ORG_UNIT\" = \'' + str(districtID) + '\'')

arcgisscripting.ExecuteError: ERROR 000358: Invalid expression

Failed to execute (SelectLayerByAttribute).

steve....@gov.bc.ca

unread,
Feb 11, 2011, 3:15:56 PM2/11/11
to geop...@googlegroups.com
The stripped down script runs through the district file okay, so the select statement is solid. Something about what I do in the subsequent steps makes things go caphlooey

Fran Tarkington

unread,
Feb 11, 2011, 4:06:29 PM2/11/11
to geop...@googlegroups.com
Ok ok I think I have an idea!

1) You create a search cursor on the layer fdistricts and then start iterating through that layer.

2) Then inside the loop you change the selection set on the same layer that the cursor is pointing to, ie the fdistricts layer

3) at the bottom of the code that is looping you request a new fdistrict.  I'm not sure what is getting returned but I would expect its a blank value or something like that as in step 2 you limited the records in this feature layer to 1.  I would have expected the script to exit the loop as the ws variable should be a null value.

Solution:

Either create two featurelayers on the forest districts, one that is used by the cursor and the other that is used to specify a single forest district.

OR

You could iterate through your cursor dumping the forest districnt ORG_UNIT values into a python list and then iterate through that list.
Example

orgUnitList = []
wss = gp.searchcursor(fdistricts)
ws = wss.next()
while ws:
    districtID = ws.getvalue("ORG_UNIT")
    orgUnitList.append(districtID)
    ws = wss.next()

for districtID in orgUnitList:
    selectFdistrict = gp.SelectLayerByAttribute(fdistricts, "NEW_SELECTION", '\"ORG_UNIT\" = \'' + str(districtID) + '\'')
    # so on and so forth!

Let me know if that sorts it out?

Cheers

Fran




You are creating a searchcursor on the featurelayer fdistricts.  The cursor iterates/loops through each of the selected records in that feature layer.  Then inside the loop you are selecting a single record from that featurelayer.  When you get to the bottom of the loop and call the next method on the cursor, I'll bet its retrieving a blank record or something because you have limited the number or


On Fri, Feb 11, 2011 at 12:15 PM, <steve....@gov.bc.ca> wrote:
The stripped down script runs through the district file okay, so the select statement is solid. Something about what I do in the subsequent steps makes things go caphlooey

--

steve....@gov.bc.ca

unread,
Feb 11, 2011, 5:39:41 PM2/11/11
to geop...@googlegroups.com
I decided to try the easiest fix first and just create a second feature layer from the districts and that solve the problem.
 
I think you're right, for some reason it is not releasing the selection on the districts layer when it goes through the
next iteration and so the search cursor moves to the next record (I've confirmed this as i get a new value for fdistrictID)
but I think that the select tries to select from the previously selected layer and it can't 'see' any other records (despite
the "NEW_SELECTION" parameter). Oh well, it works now. Thank you very much Fran (Kevin). THAT'S INCREDIBLE!
Reply all
Reply to author
Forward
0 new messages