Select to view content in your preferred language

Update all View Layers to Match Updated Hosted Feature Layer Fields

851
5
Jump to solution
11-07-2023 06:10 AM
Labels (1)
GIS_utahDEM
Frequent Contributor

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!!

 

0 Kudos
1 Solution

Accepted Solutions
MarkTorrey
Esri Contributor

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}

View solution in original post

0 Kudos
5 Replies
Mark_T
by
New Contributor

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})

 

 

 
0 Kudos
GIS_utahDEM
Frequent Contributor

This is what "fields" looks like:

GIS_utahDEM_0-1699380630305.png

This is what "dict_fields" looks like

GIS_utahDEM_1-1699380690543.png

 

I am looping through each view, with the specific information about that view captured in lines 19-22

 

 

 

0 Kudos
MarkTorrey
Esri Contributor

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}
0 Kudos
GIS_utahDEM
Frequent Contributor

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. 

0 Kudos
MarkTorrey
Esri Contributor

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.

0 Kudos