Hello! I have a Hosted Feature Layer with a large number of views (one for each jurisdiction in my state). I have made some updates to the main hosted feature layer (added a couple of fields), and I want to update all of the hosted feature layer views to match. I am trying to update by getting the fields from the main layer and using an update dictionary. My code runs, but when I open a view layer in AGOL the fields have not been updated. I've attached the relevant code I'm using below, particularly in rows 1-2 & 26-34:
import json
fields = ucip_properties.fields
# Loop through the regional division to create the views
for index, county in enumerate(counties_munis):
county_name = counties_munis.features[index].attributes['NAME']
print(county_name)
view_name = 'UCIP_' + county_name + "_LIVE_View"
print(view_name)
# Get the geometry for the regions
view_geom = counties_munis.features[index].geometry.get('rings')
name_avail = cm.is_service_name_available(service_name = view_name,service_type = "featureService")
# Check if view exists
if name_avail == True:
# CODE TO CREATE VIEW
else:
print(view_name," Exists")
# Search for newly created View
view_search = my_agol.content.search(view_name)[0]
view_flc = FeatureLayerCollection.fromitem(view_search)
service_layer = view_flc.layers[0]
layerTags = [county_name,view_name,"UCIP","View Layer"]
# Populate the update_dict with tags and fields
dict_fields = json.loads(f'{fields}')
print(dict_fields)
update_dict = {"tags":layerTags,"fields":dict_fields}
#print(service_layer.properties.tags)
# Update the definition to include the tags
view_search.update(update_dict)
print("Added tags to ",view_name)
print('Done!')
ideas? thoughts? alternative solutions? thanks!!
Solved! Go to Solution.
If you want all the fields and not a subset then you should be able to do something like this:
layerTags = [county_name, view_name, "UCIP", "View Layer"]
# Populate the update_dict with tags and fields
dict_fields = [{"name":f"{f.name}", "visible":True} for f in fields]
print(dict_fields)
update_dict = {"tags": layerTags, "fields": dict_fields}
Hi @GIS_utahDEM, What's the format of your `fields` variable? It will need to be a list of key, value pairs.
dict_fields = [{"name": fieldName, "visible":True/False},...].
Here's a small example that updates the fields of an existing view by iterating through the original layers fields and adding only a subset.
from arcgis.gis import GIS
# Set up some variables
params = {
"view_id": "e1fa73f21d0e42e9b208114ccdce04a1", # id of existing view
"include_fields": ["apn", "usetype", "roll_landv"] # limit the fields we want in the view to these three
}
# connect
portal = GIS(username="USERNAME", password="PASSWORD")
print(f"logged in to {portal.properties.name} as {portal.properties.user.username}")
# Get the existing view by item id
view = portal.content.get(params["view_id"])
# Get a reference to the source feature layer,
source_fl = view.related_items("Service2Data")[0]
# Get a list of all the fields on the source feature layer
source_flds = source_fl.layers[0].properties.fields
# create a list of key, value (name, visible) objects representing the subset of fields from the source layer we want included in the view
vis_flds = [{"name":f"{f.name}", "visible": True} if f.name in params["include_fields"] or f.type == "esriFieldTypeOID" else {"name":f"{f.name}", "visible": False} for f in source_flds]
# update the view definition with our new list
view.layers[0].manager.update_definition({"fields": vis_flds})
This is what "fields" looks like:
This is what "dict_fields" looks like
I am looping through each view, with the specific information about that view captured in lines 19-22
If you want all the fields and not a subset then you should be able to do something like this:
layerTags = [county_name, view_name, "UCIP", "View Layer"]
# Populate the update_dict with tags and fields
dict_fields = [{"name":f"{f.name}", "visible":True} for f in fields]
print(dict_fields)
update_dict = {"tags": layerTags, "fields": dict_fields}
Thanks! Would that impact anything about the fields (i.e. domains/lists), I'm not very familiar with this and from how I understand the code it would only carry over the field names and nothing else?
I am just trying to update all the views to match the original -- so if I add or delete a few fields on the original, I want to be able to run this so all the views stay up to date.
This is just telling the layer views what fields to make visible and won't affect any other properties of the fields. You can run this anytime the source feature service is updated.