Select to view content in your preferred language

Update Cursor not deleting all necessary features in AGOL Feature Layer

352
0
11-08-2022 08:03 AM
Labels (1)
by Anonymous User
Not applicable

Hi All,

I have taxlot data stored in AGOL with related tables, and I have a piece of code that finds and deletes records in the related tables that are not related to a record in the taxlot data. This is ultimately achieved using an update cursor. The code works perfectly on locally stored data, but the issue arises when I try to enact the script on hosted feature layers/tables in AGOL. It will get to 8000 records and then move on to the next table, regardless of how many records there actually are to process. Can anyone determine if I am missing something?

def main(taxlots: object, tables: list[object], taxlotJoinField: str, tableJoinField: str, actuallyDelete: bool) -> None:

# Used for debugging progress bars if the script runs too fast to see them
def insertDelay() -> None:
#time.sleep(0.0005)
pass

arcpy.AddMessage(f"Actually delete: {actuallyDelete}")
arcpy.AddMessage(f"Analyzing Taxlots Feature Class: {taxlots}")
arcpy.SetProgressor("default", "Counting rows...")

# Find the expected counts, for showing a progress bar
expectedTaxlotCount: int = int(arcpy.GetCount_management(taxlots)[0])

arcpy.AddMessage(f"Taxlot Count (in table): {expectedTaxlotCount:,}")

taxlotCount = 0
mapTaxlotNumbers: set[str] = set()

# Find the taxlot keys
with arcpy.da.SearchCursor(taxlots, [taxlotJoinField]) as cursor:
for row in cursor:

arcpy.SetProgressor("step", f"Collecting taxlots: {taxlotCount + 1:,} / {expectedTaxlotCount:,}", min_range=0, max_range=expectedTaxlotCount)
arcpy.SetProgressorPosition(taxlotCount)

insertDelay()

taxlotCount += 1
mapTaxlotNumbers.add(row[0])

arcpy.AddMessage(f"Collected Taxlots: {taxlotCount:,}")

# For each table, delete rows that aren't in the taxlot keys above
for tableIndex, table in enumerate(tables):
arcpy.AddMessage(f"Processing table: {table}")

expectedCount = int(arcpy.GetCount_management(table)[0])

includedCount = 0
excludedCount = 0
totalCount = 0

with arcpy.da.UpdateCursor(table, [tableJoinField]) as cursor:
for row in cursor:

arcpy.SetProgressor("step", f"Processing table {tableIndex + 1:,} / {len(tables):,}: {totalCount + 1:,} / {expectedCount:,}", min_range=0, max_range=expectedCount)
arcpy.SetProgressorPosition(totalCount)

totalCount += 1

insertDelay()

if row[0] in mapTaxlotNumbers:
includedCount += 1
else:
excludedCount += 1

if actuallyDelete:
cursor.deleteRow()

arcpy.AddMessage(f"\tRows in taxlots layer: {includedCount:,}\n\tNot in layer: {excludedCount:,}\n\tTotal: {totalCount:,}\n\tExcess deleted: {actuallyDelete}")

arcpy.AddMessage("Processing complete!")

class DeleteNonAssociatedTaxlotRows(object):
"""A script tool class for ArcGIS"""
def __init__(self) -> None:
self.label = "Delete Non Associated Taxlot Rows"
self.description = "Deletes related table rows that are not associated with a taxlots layer."
self.canRunInBackground = False

def getParameterInfo(self) -> list[arcpy.Parameter]:

taxlotsParam = arcpy.Parameter(
name="Taxlots",
displayName="Taxlots",
direction="Input",
datatype="DEFeatureClass",
parameterType="Required")

tablesParam = arcpy.Parameter(
name="Tables",
displayName="Tables",
direction="Input",
datatype="Table",
parameterType="Required",
multiValue=True)

taxlotJoinFieldParam = arcpy.Parameter(
name="TaxlotJoinField",
displayName="Taxlot Join Field",
direction="Input",
datatype="GPString",
parameterType="Required")

tableJoinFieldParam = arcpy.Parameter(
name="TableJoinField",
displayName="Table Join Field",
direction="Input",
datatype="GPString",
parameterType="Required")

actuallyDeleteParam = arcpy.Parameter(
name="ActuallyDelete",
displayName="Actually Delete",
direction="Input",
datatype="GPBoolean",
parameterType="Required")

taxlotJoinFieldParam.value = "MapTaxlot"
tableJoinFieldParam.value = "MapTaxlot"
actuallyDeleteParam.value = False

return [taxlotsParam, tablesParam, taxlotJoinFieldParam, tableJoinFieldParam, actuallyDeleteParam]

def isLicensed(self) -> bool:
return True

def updateParameters(self, parameters: list[arcpy.Parameter]):
return

def updateMessages(self, parameters: list[arcpy.Parameter]):
return

def execute(self, parameters: list[arcpy.Parameter], messages):
taxlots = parameters[0].value
tables = parameters[1].values
taxlotJoinField: str = parameters[2].value
tableJoinField: str = parameters[3].value
actuallyDelete: bool = parameters[4].value == True

#arcpy.AddMessage(f"String: Taxlots: {taxlots}, Tables: {tables}")
#arcpy.AddMessage(f"Type: Taxlots: {type(taxlots).__name__}, Tables: {type(tables).__name__}")
#arcpy.AddMessage(f"Table count: {len(tables)}, tables[0]: {tables[0]}, type(tables[0]).__name__: {type(tables[0]).__name__}")

main(taxlots, tables, taxlotJoinField, tableJoinField, actuallyDelete)

def postExecute(self, parameters: list[arcpy.Parameter]):
return
0 Kudos
0 Replies