Using variables inside arcpy functions

9232
5
08-16-2012 03:28 AM
AnthonyCheesman1
Occasional Contributor II
Hello

Caution... Python rookie here.

I am sure this will be a very easy answer, but for the life of me I can't figure it out.

I am trying to write an iterator that will cycle through the features within a feature class, checking each of them against a values layer.

I have almost worked out how to run the iteration by identifying the OID field and the number of features, and then run a while: loop, but I have struck a problem in creating the temporary layer that will house the single feature for checking.

Code below:

# new code using OID and while loop:

num_feats = int(str((arcpy.GetCount_management(dataset_tocheck)))) #returns number of features in dataset to check. Initial result is type RETURN, covert to STRING and then to INTEGER.
descFC = arcpy.Describe(dataset_tocheck) #set descFC variable for dataset to check
OIDFieldName = str(descFC.OIDFieldName) #find OID fieldname of dataset to check, convert to STRING

oid = 0 #create OID variable for WHILE loop

arcpy.MakeFeatureLayer_management(dataset_tocheck,"dataset_tocheck_lyr") #make feature layer from feature class

while oid < num_feats: #create WHILE loop for OID in [0, num_feats]
    dataset_tocheck_subset = arcpy.SelectLayerByAttribute_management("dataset_tocheck_lyr", "NEW_SELECTION", OIDFieldName = oid)
    oid = oid + 1


The issue I am striking is using the variables OIDFieldName and oid in the SelectLayerByAttribute function. I am trying to use variables as I want to make this code as portable as possible and once it is running, assemble into a tool for corporate deployment.

Error being returned:

Traceback (most recent call last):
  File "C:\Python26\ArcGIS10.0\Lib\site-packages\Pythonwin\pywin\framework\scriptutils.py", line 326, in RunScript
    exec codeObject in __main__.__dict__
  File "U:\PythonValuesChecking\Python Scripts\ValuesChecker.py", line 70, in <module>
    dataset_tocheck_subset = arcpy.SelectLayerByAttribute_management("dataset_tocheck_lyr", "NEW_SELECTION", OIDFieldName = oid)
TypeError: SelectLayerByAttribute() got an unexpected keyword argument 'OIDFieldName'


Am I able to use variables in this manner? What am I doing wrong?
Tags (2)
0 Kudos
5 Replies
markdenil
Occasional Contributor III
the Where clause should be a string, not a keyword argument.
That means, on the one hand,  "fun with escapes and quotes"
and, on the other, a couple of options for inserting the variable.

one option:
whereClause = "\"OIDFieldName\" = '%s%'" % (oid)

another option:
whereClause = "\"OIDFieldName\" = '" + oid + "'"
(expanded a bit for visability: " \ " OIDFieldName \ " = ' " + oid + " ' "

There are other options too, check the tool help

and then you can your where string in the tool arguments:

arcpy.SelectLayerByAttribute_management("dataset_tocheck_lyr", "NEW_SELECTION", whereClause)
0 Kudos
ChristopherThompson
Occasional Contributor III
instead of using a while loop here, you probably want to use a search cursor in concert with a for loop, which lets you move row by row through a table (or feature by feature in a featureclass or a shapefile) performing the actions you want.  Other cursors available are update and insert cursors.  Generally this would look something like this:
import arcpy
fc = arcpy.MakeFeatureLayer_management(dataset_tocheck,"dataset_tocheck_lyr") #make feature layer from feature class
qry = #an appropriate where clause statement here
rows = arcpy.SearchCursor(fc,qry,'','Field1;Field2,...Fieldx')
for row in rows:
    ... code for comparing your layer against a values layer here.. 


That last bit could be tricky depending on the sort of evaluation you needed to make against your comparison layer, if its just checking to see if the values in your search cursor are in the range of values in the comparison layer, that should be relatively simple.. but if there is a relationship somehow - feature x is the same value as in feature y.. that could be more challenging.  Another useful thing about cursors is that they honor any selection currently made in a table/feature class.  So if you have a layer that you made a select by location from - you could then use that layer in your search cursor and only the selected items would be searched.  Same would be true if you made a Selection by attributes.  On another thought, depending on what you are doing, I generally recommend avoiding the use of the OID/FID for much of anything, primarily because those fields can change as the underlying data are edited, so using some other stable field to uniquely ID a feature is usually a better option.  For one off products, probably not a huge issue, but if you wanted to make a layer file from your selection.. using a OID as part of a definition query could be a problem down the road.
0 Kudos
KenCarrier
Occasional Contributor III
Try this


querystring = " \"{0}\" = {1} ".format(OIDFieldName,oid))
dataset_tocheck_subset = arcpy.SelectLayerByAttribute_management("dataset_tocheck_lyr", "NEW_SELECTION",where_clause=querystring)

If it is a true OID field it is probably of type integer which means you do not encapsulate the value in single quotes. Only strings or text fields require the use of single quotes I believe.

I have also noticed when passing into the where_clause you need a space right after the first double quote and a space before the last double quote.

Hope this helps!
0 Kudos
AnthonyCheesman1
Occasional Contributor II
Thanks folks, there looks to be some excellent answers here. Once I get a chance to get my head back in the code later today I'll try these options.

The reason I am using this method is that I need to pull out each feature individually, and run a spatial selection against it, and a bunch of other datasets, and report back in a unique text file for each feature. The list of the other datasets is maintained in a dbf table, and I'll use a search cursor to flick through those.

I may be back for more help yet!
0 Kudos
AnthonyCheesman1
Occasional Contributor II
OK I think I've solved it. The special characters got me thinking, and while I can't get my head around them completely as yet, I can see why they are used. I also prefer to use a solution that I can comprehend and then use this as a building block for more learning.

I ended up creating a variable called sqlquery outside of the function, by concatenating together the OIDFieldName and the oid, and I then pass this variable through the function:

while oid < num_feats: #create WHILE loop for OID in [0, num_feats]
    sqlquery = OIDFieldName + "=" + str(oid) #form sqlquery outside of the function and then pass thru using special character \
    print sqlquery # temp code to check how sqlquery variable appears and to check progression of the loop
    arcpy.MakeFeatureLayer_management(dataset_tocheck, "dataset_tocheck_lyr", "\"sqlquery\"")
    oid = oid + 1


I haven't assembled the rest of the function yet, but I have inserted the print sqlquery line into the loop to see that it iterates through correctly.

Cross fingers, this might work.

Thanks everyone for their responses.
0 Kudos