[GIS] Bulk selection by ObjectID using arcpy

arcgis-10.3arcgis-desktoparcpyversioning

Trying to bulk update versioned Feature Classes containing in excess of 30,000 records is causing issue due to the Reconcile/Post process taking too long and ending up with the notice saying that the target version has changed and user must Reconcile and Post again (and whole process repeats).

I have attempted to write a little script that will create Subsets (containing about 5000 records) of my original selection and run the Calculate Field, Reconcile, and Post functions on each subset rather than the entire selection.

I can get the list of ObjectIDs of the entire original selection using desc.FIDSet, however all the documentation points towards FIDSet being Read Only. In the script I have generated a selection query to use in the SelectLayerByAttribute but I'd like to know if there is a way to just recreate the FIDSet (or alternative term if not FIDSet) rather than passing through the Select query.

Or is there a better way to achieve what I'm attempting?

desc = arcpy.Describe(FeatureLayer) # Enables listing selected records by ObjectID through FIDSet

if desc.FIDSet != '': # Check if there are selected records
    FullSel = desc.FIDSet.split(";") # Create list of ObjectIDs of selected records
    print "Number of selected features: {}".format(len(desc.FIDSet.split(";")))

    while FullSel: # Keep going while there are still records to process
        SubsetSel = [] # Create SubsetSel list for groups of selected features
        for Sel in FullSel:
            if len(SubsetSel) < MaxLoopFeatures: # SubsetSel list will only have maximum number of features from MaxLoopFeatures
                SubsetSel.append(Sel) 

        ##======================================
        ## Is there a better way to do this??
        ##======================================
        query = 'OBJECTID IN (' + ','.join(map(str, SubsetSel)) + ')' # Create query for SelectlayerByAttribute to reselect features using SubsetSel
        ##print query
        arcpy.SelectLayerByAttribute_management(FeatureLayer, "NEW_SELECTION", query) # Reselect features
        ##======================================
        ##======================================

        desc2 = arcpy.Describe(FeatureLayer)
        print "Selection Set: {}".format(desc2.FIDSet)
        print "Number of selected features: {}".format(len(desc2.FIDSet.split(";")))

        # Run intended process here
        #arcpy.CalculateField_management()
        #arcpy.ReconcileVersion_management()

        FullSel = [x for x in FullSel if x not in SubsetSel] # Remove processed features from FullSel and repeat on remaining features
else:
    print "Nothing Selected"

Best Answer

Both select by attribute and field calculator are very slow. Moreover I found that calculator expressions aren’t easy to build.

This is why I am suggesting to use da.UpdateCursor with sql_clause to split dataset in groups and to modify field(s) values.

BTW FIDset changes automatically, no need to re-describe FeatureLayer every time

Related Question