Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am a total beginner when it comes to python. I received some help already getting this code started but I hit a wall. I have a directory with 200 folders, each with a geodatabase, feature dataset, and point line and polygon feature classes. Each feature class has a field "Label" in the attribute table. I need to be able to run a search through each feature classes' attribute table and return a specific string value. For example, I need to find all feature classes where diabase is in the label field. The output would give me only the feature classes that contain diabase in the label field. I created a temp feature layer from each feature and did a select by attribute to see if get count returns anything. Here's my code:

import arcpy
arcpy.env.workspace = "X:"
ws = arcpy.ListWorkspaces("*","Folder")
arcpy.env.overwriteOutput = True
tempLayer = r"in_memory\templayer"
field = "Label"
value = "diabase"
where = "%s = '%s'" % (field,value)
dhList = []
for w in ws:
     arcpy.env.workspace = w
     gdb = arcpy.ListWorkspaces("*", "Access")
     for fc in gdb:
         arcpy.env.workspace = fc
         fcl = arcpy.ListDatasets("*", "Feature")
         for fcc in fcl:
             arcpy.env.workspace = fcc
             fccl = arcpy.ListFeatureClasses("*", "All")
             for stil in fccl:
                 arcpy.MakeFeatureLayer_management(stil, tempLayer, where)
                 arcpy.SelectLayerByAttribute_management(tempLayer,"SUBSET_SELECTION")
                 count = str(arcpy.GetCount_management(tempLayer).getOutput)
                 print count
                 if count > 0:
                    dhList.append(stil)
for item in dhList:
     print item

The output is giving me a list of all of the feature classes in the directory instead of only the feature classes with diabase. What am I doing wrong?

Thanks for any and all help in advance.

share|improve this question
add comment

2 Answers 2

up vote 2 down vote accepted

An alternative to using the SelectLayerByAttribute_management tool would be to create a SearchCursor on each featureclass that you are stepping through, in your case represented by the variable "stil". Use a whereclause on the cursor of "[Label] = 'diabase'". For each featureclass where the SearchCursor returns a row that is not equal to "None", this means the attribute was found, and you can add those to your list.

See the code below for an example:

import arcpy  #Imports arcpy module which includes function info and license ifno
arcpy.env.workspace = "X:"  #Set environment workspace to X: drive
ws = arcpy.ListWorkspaces("*","Folder")  #Assigns list of folder type workspaces to variable "ws"
arcpy.env.overwriteOutput = True
dhList = [] #Sets value of variable "dhList" to empty, thus defining as list variable
for w in ws:  #Starts for loop, for each "w" workspace in "ws" workspace list set above
     arcpy.env.workspace = w #Set arcpy environment to "w" folder workspace
     gdb = arcpy.ListWorkspaces("*", "Access") #set variable "gdb" to list of Personal Geodatabases, which are MS Access databases, found in "w" workspace
     for fc in gdb: #Starts for loop, Iterates through "fc" geodatabase in "gdb" list of PGDB workspaces
         arcpy.env.workspace = fc #Again sets arcpy workspace to current geodatabase in For Loop
         fcl = arcpy.ListDatasets("*", "Feature") #Set "fcl" variable to list of Feature datasets in current "fc" personal geodatabase
         for fcc in fcl: #Starts for loop, iterate through each "fcc" feature dataset in "fcl" list of feature datasets
             arcpy.env.workspace = fcc  #Set arcpy workspace to current feature dataset in For Loop
             fccl = arcpy.ListFeatureClasses("*", "All") #Set "fccl" variable to list of featureclasses contained in current "fcl" feature dataset
             for stil in fccl: #Starts for loop, iterate through each "stil" featureclass in "fccl" list of feature classes
                 stilfields = arcpy.ListFields(stil) #Set "stilfields" variable to list of fields contained in current "stil" featureclass
                 for field in stilfields: #Starts For Loop, iterate through each "field" field in "stilfields" list of fields
                     fieldname = "Label" #Set "fieldname" variable to "Label"
                     if field.name == fieldname: #If 'Name' Property of "field" variable equals value of "fieldname" variable then do the following.  Basically this tests to see if the featureclass contains a field named "Label"
                         newname = arcpy.AddFieldDelimiters(gdb,fieldname) #Starting to build SQL string to query value of "Label" field.  Each geodatabase type requires different notation in the SQL String.  this function adds the appropriate wrapper, whether single or double quotes or brackets to value of "fieldname" variable, based on the value of "gdb" variable, and assigns new string to "newname" variable.
                         attvalue = "diabase" #Set "attvalue" variable equal to string "diabase"
                         sqlstring = newname + " = " + attvalue #Set "sqlstring" variable equal to "newname" variable + equals sign + "attvalue" variable, creates string equal to "[Label] = 'diabase'"
                         fcrows = arcpy.SearchCursor(stil,sqlstring) #Sets "fcrows" variable equal to rows in "stil" featureclass that satisfy the "sqlstring" variable.  So any rows that have a value in the "Label" field equal to "diabase" will be added to this list
                         fcrow = None #Set "fcrow" variable equal to None
                         fcrow = fcrows.next() #Set "fcrow" variable equal to the next value in the "fcrows" list variable
                         if not (fcrow == None): #Test to see if "fcrow" variable is NOT equal to None.  If so, that means that "fcrows" list contained 1 or more values.  This means that "stil" featureclass contained rows that matched your sql string.
                             dhList.append(stil) #Adds "stil" featureclass to "dhList" list, which we defined at the top of the script.
                         break #Breaks out of the For Loop going through the field list.  If it reached this point, it means that it found the "Label" field and matched the attribute, so no need to look at further fields in this featureclass.
#At the bottom of each For statement, there is an implied Loop statement.  So at the bottom of the code contained in the For statement, it will go back to the top, take the next value in the list and start over until there are no more values to evaluate, then it will move on to the next code block.  For Loops are defined by indentations.  Code below the For statement that is indented is inside the For Loop.
for item in dhList:
     print item

I am pretty basic with my coding skills, but this seems like it should do the trick.

Good luck!
Russell

share|improve this answer
    
Thanks for your reply, however, there was a problem somewhere. AttributeError: 'Cursor' object has no attribute 'count'. Any idea what this might mean? –  user7278 May 2 '12 at 17:16
    
@user7278, I have actually edited my answer because I realized that same thing. I changed it to look to see if any rows were added to the cursor instead. If a row is added, then it found features that matched the query, and thus should be included in your selection set. Sorry for the confusion. –  Get Spatial May 2 '12 at 17:24
    
Thank you for your help! I got it to work on my "test" directory with 3 folders. I tried it on my large directory but some feature classes do not have the "Label" field so it gives me an error. Is there a way to skip the feature classes that do not have the field Label? –  user7278 May 2 '12 at 18:04
    
This is the error: General function failure [bluesa_1] Too few parameters. Expected 1. –  user7278 May 2 '12 at 18:06
    
@user7278, I edited the post again to put in search string for the "Label" field name. Now, if it finds it in the featureclass, it should then run the SearchCursor. Give it a try and see if it works. –  Get Spatial May 2 '12 at 18:07
show 4 more comments

I believe that the error is in your where clause. The first %s need to be enclosed in quotations for the SQL clause to run properly.

where = " \"%s\" = '%s'" %(field,value)

We are using the python escape character \ to be able to have multiple double quotes in a row.

In a personalGBD the field needs to be enclosed in braces [].

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00170000006p000000

share|improve this answer
3  
I strongly recommend using the AddFieldDelimiters function to automatically add the correct field delimiters for your field name instead of hardcoding them or writing cases for each workspace type. –  blah238 May 2 '12 at 16:58
    
@blah238 - I did not know that function existed, but it certainly makes dealing with different data sources easier! –  Get Spatial May 2 '12 at 23:05
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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