Hello everyone,
I am trying to create a join between 2 hosted feature layers in ArgGIS API for Python (on ArcGIS Online). I keep receiving a type error and I'm not really sure how to approach it.
Exception: A general error occurred: Object of type 'set' is not JSON serializable
Here is the code and the output:
joinData = join_features(target_layer=facilities,
join_layer=counties,
output_name="Facility_county_join",
join_operation="JoinOneToOne",
spatial_relationship="",
attribute_relationship=[{"NAME", "Facility"}],
summary_fields=[{"Current_Status", "SUM"}])
TypeError Traceback (most recent call last) /opt/conda/lib/python3.6/site-packages/arcgis/gis/_impl/_con/_connection.py in post(self, path, params, files, **kwargs) 662 if isinstance(v, (dict, list, tuple, bool)): --> 663 params[k] = json.dumps(v) 664 elif isinstance(v, PropertyMap): /opt/conda/lib/python3.6/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw) 230 default is None and not sort_keys and not kw): --> 231 return _default_encoder.encode(obj) 232 if cls is None: /opt/conda/lib/python3.6/json/encoder.py in encode(self, o) 198 # equivalent to the PySequence_Fast that ''.join() would do. --> 199 chunks = self.iterencode(o, _one_shot=True) 200 if not isinstance(chunks, (list, tuple)): /opt/conda/lib/python3.6/json/encoder.py in iterencode(self, o, _one_shot) 256 self.skipkeys, _one_shot) --> 257 return _iterencode(o, 0) 258 /opt/conda/lib/python3.6/json/encoder.py in default(self, o) 179 raise TypeError("Object of type '%s' is not JSON serializable" % --> 180 o.__class__.__name__) 181 TypeError: Object of type 'set' is not JSON serializable During handling of the above exception, another exception occurred: Exception Traceback (most recent call last) <ipython-input-26-cf1ae0f3dbb2> in <module> 5 spatial_relationship="", 6 attribute_relationship=[{"NAME", "Facility"}], ----> 7 summary_fields=[{"Current_Status", "SUM"}]) /opt/conda/lib/python3.6/site-packages/arcgis/features/summarize_data.py in join_features(target_layer, join_layer, spatial_relationship, spatial_relationship_distance, spatial_relationship_distance_units, attribute_relationship, join_operation, summary_fields, output_name, context, gis, estimate, future) 640 if 'summary_fields' not in params: 641 params['summary_fields'] = summary_fields --> 642 return gis._tools.featureanalysis.join_features(**params) /opt/conda/lib/python3.6/site-packages/arcgis/_impl/tools.py in join_features(self, target_layer, join_layer, spatial_relationship, spatial_relationship_distance, spatial_relationship_distance_units, attribute_relationship, join_operation, summary_fields, output_name, context, estimate, records_to_match, future) 2746 output_name=output_name, 2747 context=context, gis=self._gis, -> 2748 future=True) 2749 gpjob._is_fa = True 2750 if future: <string> in join_features(target_layer, join_layer, spatial_relationship, spatial_relationship_distance, spatial_relationship_distance_units, attribute_relationship, join_operation, summary_fields, records_to_match, output_name, context, join_type, gis, future) /opt/conda/lib/python3.6/site-packages/arcgis/geoprocessing/_support.py in _execute_gp_tool(gis, task_name, params, param_db, return_values, use_async, url, webtool, add_token, return_messages, future) 388 job_info = gptool._con.post(submit_url, gp_params) 389 else: --> 390 job_info = gptool._con.post(submit_url, gp_params) 391 job_id = job_info['jobId'] 392 if future: /opt/conda/lib/python3.6/site-packages/arcgis/gis/_impl/_con/_connection.py in post(self, path, params, files, **kwargs) 698 "URL scheme must be provided: %s" % errMS) 699 except Exception as e: --> 700 raise Exception('A general error occurred: %s' % e) 701 except: 702 import traceback Exception: A general error occurred: Object of type 'set' is not JSON serializable
Thank you in advance!
Solved! Go to Solution.
Okay with some help between @DanPatterson and some documentation here https://developers.arcgis.com/rest/services-reference/join-features.htm I managed to get it working. I was missing some parameters in the attribute relationship. Final code:
joinData = join_features(target_layer=facilities,
join_layer=counties,
output_name="Facility_county_join",
join_operation="JoinOneToOne",
spatial_relationship="",
attribute_relationship=[{"targetField": "NAME", "joinField": "Facility", "operator": "egual"}],
summary_fields=[{"statisticType": "Sum", "onStatisticField": "Current_status"}])
Do you need the { } within the list
currently you have defined a set within a list.
a = [{"NAME", "Facility"}]
type(a[0])
set
a0 = ["NAME", "Facility"]
type(a0)
list
type(a0[0])
str
I don't think so. I did some playing around and I think the attribute relationship needs the { }, but now I'm having an error with the summary fields, just saying "Job Failed".
joinData = join_features(target_layer=facilities,
join_layer=counties,
output_name="Facility_county_join",
join_operation="JoinOneToOne",
spatial_relationship="",
attribute_relationship={"NAME", "Facility"},
summary_fields=["Current_Status", "SUM"])
both parameters say a list of dicts.
attribute_relationship = [{"NAME": "Facility"}]
summary_fields = [{"Current_Status": "SUM"}]
a = [{"NAME": "Facility"}]
type(a)
list
type(a[0])
dict
Of course I can't find any example syntax in the documents, so if it is true, try a list of dict
A colon makes the difference
type({"NAME", "Facility"})
set
type({"NAME": "Facility"})
dict
ADDENDUM
Found an example in their code
summary_fields=[{"statisticType": "Mean", "onStatisticField": "Population"}
aka. a list of dictionary items
Okay with some help between @DanPatterson and some documentation here https://developers.arcgis.com/rest/services-reference/join-features.htm I managed to get it working. I was missing some parameters in the attribute relationship. Final code:
joinData = join_features(target_layer=facilities,
join_layer=counties,
output_name="Facility_county_join",
join_operation="JoinOneToOne",
spatial_relationship="",
attribute_relationship=[{"targetField": "NAME", "joinField": "Facility", "operator": "egual"}],
summary_fields=[{"statisticType": "Sum", "onStatisticField": "Current_status"}])
Appreciated for posting your final solution .