Specify a Query in Search Cursor

1147
4
Jump to solution
09-22-2016 07:47 AM
ZacharyHart
Regular Contributor

Basically I'm trying to create a selection that satisfies a random criteria AND a query based on an attribute field. Here is some sample code I found on StackExchange:

def SelectRandomByCount (layer, count):
    import random
    layerCount = int (arcpy.GetCount_management (layer).getOutput (0))
    if layerCount < count:
        print "input count is greater than layer count"
        return
    oids = [oid for oid, in arcpy.da.SearchCursor (layer, "OID@")]
    oidFldName = arcpy.Describe (layer).OIDFieldName
    delimOidFld = arcpy.AddFieldDelimiters (layer, oidFldName)
    randOids = random.sample (oids, count)
    oidsStr = ", ".join (map (str, randOids))
    sql = "{0} IN ({1})".format (delimOidFld, oidsStr)
    arcpy.SelectLayerByAttribute_management (layer, "", sql)

What I need is this in conjunction with a query (from the same input later) where FIELD = Value (for a string field).

I have reviewed the ESRI help document related to Specifying a query in Python, but am having difficulty understanding how to implement this.

0 Kudos
1 Solution

Accepted Solutions
JakeSkinner
Esri Esteemed Contributor

Hi Zachary,

I would recommend creating a Feature Layer.  You can specify a query when doing so.  Ex:

arcpy.MakeFeatureLayer_management("C:/data/mexico.gdb/cities","cities_lyr", "POPULATION > 50000")

You can then pass the feature layer to the function to retrieved from StackExchange.

View solution in original post

4 Replies
JakeSkinner
Esri Esteemed Contributor

Hi Zachary,

I would recommend creating a Feature Layer.  You can specify a query when doing so.  Ex:

arcpy.MakeFeatureLayer_management("C:/data/mexico.gdb/cities","cities_lyr", "POPULATION > 50000")

You can then pass the feature layer to the function to retrieved from StackExchange.

ZacharyHart
Regular Contributor

Jake, this is great and will totally get me there. To be clear, is there a way to build the sql query using a logical operator 'AND'? Here's an attempt but the query fails:


def SelectRandomByCount (layer, count):
    import random
    layerCount = int (arcpy.GetCount_management (layer).getOutput (0))
    if layerCount < count:
        print "input count is greater than layer count"
        return
    oids = [oid for oid, in arcpy.da.SearchCursor (layer, "OID@")]
    oidFldName = arcpy.Describe (layer).OIDFieldName
    delimOidFld = arcpy.AddFieldDelimiters (layer, oidFldName)
    TypeField = arcpy.AddFieldDelimiters (layer, "OS_TYPE")
    #TypeField = "OS_TYPE"
    Type = 'S3A'
    randOids = random.sample (oids, count)
    oidsStr = ", ".join (map (str, randOids))
    sql = """ {0} IN ({1}) AND {2} = '{3}' """.format (delimOidFld, oidsStr, TypeField, Type)
    print sql
    arcpy.SelectLayerByAttribute_management (layer, "", sql)

[EDIT: fixed...i just had to for

I ask this because what I'm actually looking to do this for the same field to satisfy 5 different queries...say for "FIELD" = 'Value1', then "FIELD" = 'Value2'...etc. I guess that would be a loop within a loop? If this qualifies as another question altogether, I'll mark yours as correct.

I'll hammer away at this, but do appreciate the insight!

JakeSkinner
Esri Esteemed Contributor

Yes, you would want to do a loop.  Ex:

import arcpy
from arcpy import env
env.overwriteOutput = 1

values = ["Value1", "Value2", "Value3", "Value4", "Value5"]

for value in values:
    arcpy.MakeFeatureLayer_management(r"D:\Temp\Python\Test.gdb\Airports", "airports_layer", "FCC = '{0}'".format(value))
    SelectRandomByCount("airports_layer", 5)
ZacharyHart
Regular Contributor

Thanks Jake!

0 Kudos