Search code examples
pythonpandasarcgisarcpy

Circular reference error when trying to update GIS features through ArcGIS Online


I am trying to following the steps listed here to update a feature on AGOL from a local feature class. I keep getting a circular reference within the for loop and I'm not sure why it's happening.

Please see the code I'm using below.

import arcgis, arcpy, csv, os, time, copy, pandas as pd
from arcgis.gis import GIS
from pandas import DataFrame
from copy import deepcopy
gis = GIS("url", "username","pass")
fc = gis.content.get('ItemID')
flayer = fc.layers[0]
fset=flayer.query()
fields = ('GPS_Time','Visibility','EngineeringSection','Condition')
UpdateLayer  = "C:\\Users\\USer\\Documents\\ArcGIS\\Default.gdb\\Data"
UpdateTable=DataFrame(arcpy.da.FeatureClassToNumPyArray(UpdateLayer , fields, skip_nulls=True))
overlap_rows = pd.merge(left=fset.sdf, right = UpdateTable, how='inner', on='EngineeringSection')
features_for_update = []
all_features = fset.features    
for EngSec in overlap_rows['EngineeringSection']:
    original_feature = [f for f in all_features if     f.attributes['EngineeringSection'] == EngSec][0]
    feature_to_be_updated = deepcopy(original_feature)
    matching_row = UpdateTable.where(UpdateTable['EngineeringSection'] == EngSec).dropna()
    original_feature.attributes['GPS_Time'] = (matching_row['GPS_Time'])
    original_feature.attributes['Visibility'] = int(matching_row['Visibility'])
    original_feature.attributes['Condition'] = str(matching_row['Condition'])
    update_result = flayer.edit_features(updates=[original_feature])
    flayer.edit_features(updates= features_for_update)

Here is the error I receive:

Traceback (most recent call last):
  File "<stdin>", line 9, in <module>
  File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\features\layer.py", line 1249, in edit_features
default=_date_handler)
  File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\json\__init__.py", line 238, in dumps
**kw).encode(obj)
  File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
  File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
ValueError: Circular reference detected

Solution

  • Thanks for your help, I was able to get it all running with this script: I also added in some timing to see how long it was taking

    import arcpy, csv, os, time
    import pandas as pd
    from arcgis.gis import GIS
    from pandas import DataFrame
    from copy import deepcopy
    start_time = time.time()
    gis = GIS("url", "user","pass")
    fc = gis.content.get('ContentID')
    flayer = fc.layers[0]
    fset=flayer.query()
    fields = ('GPS_Time','Visibility','EngineeringSection','Condition')
    UpdateLayer  = "C:\\Users\\user\\Documents\\ArcGIS\\Default.gdb\\data"
    UpdateTable=DataFrame(arcpy.da.FeatureClassToNumPyArray(UpdateLayer , fields, skip_nulls=True))
    overlap_rows = pd.merge(left=fset.sdf, right = UpdateTable, how='inner', on='EngineeringSection')
    features_for_update = []
    all_features = fset.features
    for EngSec in overlap_rows['EngineeringSection']:
        original_feature = [f for f in all_features if f.attributes['EngineeringSection'] == EngSec][0]
        feature_to_be_updated = deepcopy(original_feature)
        matching_row = UpdateTable.where(UpdateTable['EngineeringSection'] == EngSec).dropna()
        feature_to_be_updated.attributes['GPS_Time'] = matching_row['GPS_Time'].iloc[0]
        feature_to_be_updated.attributes['Visibility'] = int(matching_row['Visibility'])
        feature_to_be_updated.attributes['Condition'] = str(matching_row['Condition'].iloc[0])
        update_result = flayer.edit_features(updates=[feature_to_be_updated])
        update_result
    elapsed_time = time.time() - start_time
    totaltime = time.strftime("%H:%M:%S", time.gmtime(elapsed_time))
    print("Total processing time: "+ totaltime)