I need to permanently sort a feature class field so I can add a sequential number based on the sort. I know I can use the sort tool, but I want to sort the existing feature without having to create another feature class. I am able to do the sequential number with the following but I need the feature class "Sub_Name" sorted. anyone have an example of how to accomplish this?
import arcpy
from itertools import count
cntr = count()
fc = 'C:\Temp\SUBS.shp'
with arcpy.da.UpdateCursor(fc,["ID","SUB_NAME"],sql_clause=(None,"ORDER BY SUB_NAME")) as cur:
for i, j in cur:
cur.updateRow([next(cntr), j])
No, I'm asking about the source data. How do you create the SUBS.shp?
Sorry, it derived from a feature class in a geodatabase.
I preform a selection by location, then I export the selected features to the shapefile.
Maybe try something like this then.
import arcpy
import os
source_fc = r"C:\Temp\some_gdb\SUBS"
sort_field_name = "SUB_NAME"
# Make new feature class for ordered rows.
out_fc = arcpy.management.CreateFeatureclass(
out_path=os.path.dirname(source_fc),
out_name="SUBS_ordered",
template=source_fc
)
# Insert the rows ordered by sub_name
source_fc_fields = [f.name for f in arcpy.ListFields(source_fc)]
with arcpy.da.SearchCursor(source_fc, "*", sql_clause=(None, f"ORDER BY {sort_field_name}")) as s_cursor:
with arcpy.da.InsertCursor(out_fc, "*") as i_cursor:
for row in s_cursor:
i_cursor.insertRow(row)
I tried to incorporate you suggestion, but I ran into an issue with the Global ID. At least I believe that is the issue.
TypeError: sequence size must match size of the row.
import arcpy, os
project = arcpy.mp.ArcGISProject("CURRENT")
arcpy.env.workspace = os.path.dirname(project.filePath)
wp = os.path.dirname(project.filePath)
outPath = r'C:\Temp\Scratchworkspace.gdb'
scr = 'SUBS'
sortedTableName = 'SUBS_ordered'
arcpy.management.MakeFeatureLayer("SUBS", "memory\SubsLyr")
arcpy.SelectLayerByLocation_management("SUBS", "WITHIN_A_DISTANCE", "SUBJECT_PROPERTY", "1 Mile", "NEW_SELECTION")
arcpy.analysis.Select("SUBS", r"memory/SubLayer1")
#--check if output feature class exists, if not, create it
if not os.path.exists(os.path.join(outPath,sortedTableName)):
out_fc = arcpy.management.CreateFeatureclass(outPath,out_name="SUBS_ordered", template=scr)
else:
try:
arcpy.DeleteRows_management(os.path.join(outPath,"SUBS_ordered"))
except:
pass
source_fc = r"memory/SubLayer1"
sort_field_name = "SUB_NAME"
source_fc_fields = [f.name for f in arcpy.ListFields(scr)]
with arcpy.da.SearchCursor(source_fc, "*", sql_clause=(None, f"ORDER BY {sort_field_name}")) as s_cursor:
with arcpy.da.InsertCursor(sortedTableName, "*") as i_cursor:
for row in s_cursor:
i_cursor.insertRow(row)
The "SUBS" is in SDE geodatabase and has GlobalID .
The "SUBS_ordered" in a file geodatabase doesn't have a GlobalID.
How can I leave out the GlobalID or other fields?
The other difference between the two is.
SubLayer1: Shape_STArea__ , Shape_STLength__
SUBS_ordered : Shape_Area, Shape_Length
They should have the same fields if you're creating the output using the subs as a template. It was hard to follow your code because there seemed to be some unused lines, redundancies, and too many different names. I did my best to refactor it. If there's a GlobalID field in Subs, it should create a GlobalID field in the Subs_Ordered output too.
import arcpy
import os
project = arcpy.mp.ArcGISProject("CURRENT")
arcpy.env.workspace = os.path.dirname(project.filePath)
arcpy.env.overwriteOutput = True
outPath = r'C:\Temp\Scratchworkspace.gdb'
source_fc = "SUBS"
sortedTableName = "SUBS_ordered"
# Select subs by location to subject property.
arcpy.management.MakeFeatureLayer(source_fc, "SubsLyr")
arcpy.management.SelectLayerByLocation(
in_layer="SubsLyr",
overlap_type="WITHIN_A_DISTANCE",
select_features="SUBJECT_PROPERTY",
search_distance="1 Mile",
selection_type="NEW_SELECTION"
)
# Make new feature class for ordered rows.
out_fc = arcpy.management.CreateFeatureclass(
out_path=outPath,
out_name=sortedTableName,
template="SubsLyr"
)
# Read through the sorted selection of subs and insert them into the output feature class.
with arcpy.da.SearchCursor("SubsLyr", "*", sql_clause=(None, "ORDER BY SUB_NAME")) as s_cursor:
with arcpy.da.InsertCursor(sortedTableName, "*") as i_cursor:
for row in s_cursor:
i_cursor.insertRow(row)