1

How do I construct an if, then statement based on a select by attribute SQL query or some other method (search cursor?)?

I am asking users to input a unique ID (arcpy.GetParameterAsText(0)), based on that ID I want to search a shapefile field for that value (arcpy.SelectLayerByAttribute_management or arcpy.SearchCursor?), if it is not found, I want to search a different shapefile. When the Unique ID is found I need to export (arcpy.CopyFeatures_management) and isolate the feature.

I am having trouble trying to find something which will indicate if the unique ID is found in the field or not.

I'm essentially looking for something like what occurs with the Verify Expression button event click -> "The expression was verified successfully, BUT NO RECORDS WERE RETURNED".

5
  • does the attribute field have the same name in every shapefile that you want to search?
    – mr.adam
    Jun 3, 2015 at 13:55
  • Yes, but I think I may just adopt a dirty work around. I may just perform a where clause with (arcpy.Select_analysis) which will generate my output shapefile if the attribute is found. Then institute the if-then-else on the condition of a feature layer exists check (arcpy.Exists).
    – pyRsq
    Jun 3, 2015 at 14:10
  • is it an integer field, or is it text? answer forthcoming...
    – mr.adam
    Jun 3, 2015 at 14:12
  • Haha, string (text). Correction, the attribute field names are currently very slightly different, requiring unique where clauses. However, they could easily be changed to be the same.
    – pyRsq
    Jun 3, 2015 at 14:25
  • well, it'll make things a lot easier if they have the same name, but you could use store the field name along with the shapefile path in the list. I make a little update.
    – mr.adam
    Jun 3, 2015 at 14:31

1 Answer 1

2

Let's say you have a list of shapefiles and the field name for the attribute is the same in each shapefile. That means you can make the SQL query in the beginning of the script, so the first bit could look like this:

search_id = arcpy.GetParameterAsText(0)

shps = [r"path\to\shp1.shp",r"path\to\shp2.shp"]
output_shp = r"path\to\output.shp"
field = "ID_FIELD_NAME"

sql = '"{0}" = \'{1}\''.format(field,search_id)

Here are two ways to go about your selection process. The first uses a where clause in the MakeFeatureLayer() and GetCount(), and the second uses a SearchCursor() to find the attribute and proceeds to MakeFeatureLayer(). I'm not sure which one is faster, but my guess is the second. Most likely, the speed is very similar if you don't have tons of shapefiles.

for shp in shps:

    # make feature layer
    if arcpy.Exists("fl"):
        arcpy.management.Delete("fl")
    fl = arcpy.management.MakeFeatureLayer(shp,"fl",sql)

    # check count of features in new feature layer, skip to next shp if it == 0
    if int(arcpy.management.GetCount(fl).getOutput(0)) == 0:
        continue

    # copy features, only happens if there is a feature in the feature layer
    arcpy.management.CopyFeatures(fl,output_shp)

and here's the second. In this one, a SearchCursor is used to check for the presence of the feature, and then the MakeFeatureLayer() is used. I think this would probably be the faster way:

for shp in shps:

    # use list comprehension with a SearchCursor to check for the id
    all_ids = [r[0] for r in arcpy.da.SearchCursor(shp,field)]
    if not search_id in all_ids:
        continue

    # now make feature layer and copy features
    if arcpy.Exists("fl"):
        arcpy.management.Delete("fl")
    fl = arcpy.management.MakeFeatureLayer(shp,"fl",sql)

    # copy features
    arcpy.management.CopyFeatures(fl,output_shp)

EDIT:

With differing field names, you can store them and iterate the shapefiles like this:

shps = [(r"path\to\shp1.shp","ID_FIELD_NAME1"),
        (r"path\to\shp2.shp","ID_FIELD_NAME2")]
output_shp = r"path\to\output.shp"

for item in shps:
    shp = item[0]
    field = item[1]
    sql = '"{0}" = \'{1}\''.format(field,search_id)

    #continue with the rest of the code as above

Your Answer

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

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