Select all features by OID

354
8
08-20-2020 02:19 PM
2Quiker
Occasional Contributor

I am trying to select all the features/attributes of a feature class but I am unable accomplish this, can someone help me out.

I have tried the following but i get arcgisscripting.ExecuteError: ERROR 000358: Invalid expression
Failed to execute (SelectLayerByAttribute)." on line 6. If this is not the best/easiest way please share what would be.

arcpy.MakeFeatureLayer_management(fc, 'FcLyr')
#oids = [row[0] for row in arcpy.da.SearchCursor('FcLyr', "OID@")]
with arcpy.da.SearchCursor('FcLyr', ["OID@"]) as selected_fc:
for row in selected_fc:
print (row)
arcpy.SelectLayerByAttribute_management('FcLyr', "NEW_SELECTION", row[0]) #"OBJECTID = {}".format(row[0])
0 Kudos
8 Replies
DanPatterson
MVP Honored Contributor

Why are you trying to select all features when you can just use the feature layer itself.  Any subsequent operations will apply to all records if none are selected or only to the selected records if a selection exists


... sort of retired...
2Quiker
Occasional Contributor

I didn't think of that but I am still curious on how you would do that with selectbyattributes or other ways.

RandyBurton
MVP Regular Contributor

The error message is occurring with the line:

arcpy.SelectLayerByAttribute_management('FcLyr',  "NEW_SELECTION", row[0]) #"OBJECTID = {}".format(row[0])

Your comment at the end was the right idea, you just needed to make row[0] a string to work in the where clause.  And row[0] by itself is not a valid where clause.

arcpy.SelectLayerByAttribute_management('FcLyr', "NEW_SELECTION", "OBJECTID = {}".format(str(row[0])))




0 Kudos
2Quiker
Occasional Contributor

Thanks but after running the code with your suggestion it takes 1.48 min,sec to only select one feature.

The following only copies one feature.

print, prints 1 over and over

1

1

1

1

arcpy.MakeFeatureLayer_management(fc, 'FcLyr')
#oids = [row[0] for row in arcpy.da.SearchCursor('FcLyr', "OID@")]
with arcpy.da.SearchCursor('FcLyr', ["OID@"]) as selected_fc:
for row in selected_fc:
#print (row)
arcpy.SelectLayerByAttribute_management('FcLyr', "NEW_SELECTION", "OBJECTID_1 = {}".format(str(row[0]))) #"OBJECTID_1 = {}".format(row[0])
result = int(arcpy.GetCount_management('FcLyr').getOutput(0))
print (result)
arcpy.CopyFeatures_management('FcLyr', "C:/Temp/blah/blah.gdb/blah")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
RandyBurton
MVP Regular Contributor

Line 8 will always print 1, since you are selecting only one feature ( where OBJECTID_1 = 123 - or some other number).  I normally wouldn't use a SearchCursor to select a group of records in this case.

I would just use the suggestion from Dan Patterson‌:

arcpy.MakeFeatureLayer_management(fc, 'FcLyr')

arcpy.management.SelectLayerByAttribute('FcLyr', "CLEAR_SELECTION")

result = int(arcpy.GetCount_management('FcLyr').getOutput(0))
print (result)

arcpy.CopyFeatures_management('FcLyr', "C:/Temp/blah/blah.gdb/blah")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
DanPatterson
MVP Honored Contributor

simply just use Switch Selection

arcpy.management.SelectLayerByAttribute("sq", "SWITCH_SELECTION", '', None)


... sort of retired...
JoshuaBixby
MVP Esteemed Contributor

I agree with Dan that all records will be processed if no selection is applied to a layer, but if a selection is applied with no records then no records will be processed.  Before processing all records in a layer, I always clear the selection to make sure all records will be processed.

>>> import arcpy
>>>
>>> fc = r"C:\tmp\fgdb.gdb\usa_states_gnlz" # path to feature class
>>> lyr_name = "usa_states"
>>>
>>> # make feature layer for testing selections
>>> arcpy.management.MakeFeatureLayer(fc, lyr_name)
<Result 'usa_states'>
>>>
>>> # get total count of records when no selection is applied
>>> arcpy.management.GetCount(lyr_name)
<Result '51'>
>>>
>>> # apply selection with no records
>>> arcpy.management.SelectLayerByAttribute(lyr_name, "NEW_SELECTION", "1=2")
<Result 'usa_states'>
>>>
>>> # no records are processed with selection with no records
>>> arcpy.management.GetCount(lyr_name)
<Result '0'>
>>> with arcpy.da.SearchCursor(lyr_name, "OID@") as cur:
... print(*cur, sep="\n")
...

>>>
>>> # clear selection to process all records
>>> arcpy.management.SelectLayerByAttribute(lyr_name, "CLEAR_SELECTION")
<Result 'usa_states'>
>>> arcpy.management.GetCount(lyr_name)
<Result '51'>
>>>

The easiest way to return all records in a data set when forced to use a SQL WHERE clause, like in Select Layer By Attribute, is to use "1=1".

>>> import arcpy
>>>
>>> fc = r"C:\tmp\fgdb.gdb\usa_states_gnlz" # path to feature class
>>> lyr_name = "usa_states"
>>>
>>> # apply selection with 1 record
>>> arcpy.management.SelectLayerByAttribute(lyr_name, "NEW_SELECTION", "STATE_NAME = 'California'")
<Result 'usa_states'>
>>> arcpy.management.GetCount(lyr_name)
<Result '1'>
>>>
>>> # select all records using 1=1
>>> arcpy.management.SelectLayerByAttribute(lyr_name, "NEW_SELECTION", "1=1")
<Result 'usa_states'>
>>> arcpy.management.GetCount(lyr_name)
<Result '51'>
>>>
DanPatterson
MVP Honored Contributor

Or more simply make a new selection without any specifications, then clear selection

arcpy.management.SelectLayerByAttribute("sq", "NEW_SELECTION", '', None)
# ---- then
arcpy.management.SelectLayerByAttribute("sq", "CLEAR_SELECTION", '', None)


... sort of retired...