Select to view content in your preferred language

How to apply attribute table settings (fields visibility and format) from one layer to another using arcpy?

180
5
a week ago
Sfortunatamente
Regular Contributor

I have 40 layers with the same table schema and I need to apply symbology and table settings from another layer. I have a template layer and applying symbology works as expected. 

Is it possible to apply fields visibility and formats as well? 

I can see pasteProperties (source_layer, {layer_paste_properties}) method but when applying in on a layer object I get the following error: AttributeError: 'Layer' object has no attribute 'pasteProperties'

L = map.addDataFromPath(r"..\Address.lyrx")
for lyr in map.listLayers():
    print(lyr.name)
    lyr.pasteProperties(L, layer_paste_properties="FIELD_PROPERTIES")

Thanks,

0 Kudos
5 Replies
DanPatterson
MVP Esteemed Contributor

Layer—ArcGIS Pro | Documentation

you should check if it is a featurelayer before trying to try to pastProperties

isFeatureLayer
(Read Only)
Returns True if a layer is a feature layer.


... sort of retired...
TonyAlmeida
MVP Regular Contributor

Try this,

import arcpy

# Load the template layer
template_layer_path = r"..\Address.lyrx"
template_layer = arcpy.mp.LayerFile(template_layer_path).listLayers()[0]

# Get your map
aprx = arcpy.mp.ArcGISProject("CURRENT")
map = aprx.listMaps("Your Map Name")[0]

# Apply symbology + field properties
for lyr in map.listLayers():
    if lyr.isFeatureLayer:
        print(f"Updating {lyr.name}...")
        arcpy.management.UpdateLayer(lyr, template_layer, True)  # True = keep data source
        print(f"Completed: {lyr.name}")

print("All layers updated successfully!")
0 Kudos
Sfortunatamente
Regular Contributor

Didn't work..

AttributeError: module 'arcpy.management' has no attribute 'UpdateLayer'

0 Kudos
TonyAlmeida
MVP Regular Contributor

try 

# Use ApplySymbologyFromLayer 
        arcpy.ApplySymbologyFromLayer_management(lyr, template_layer)
0 Kudos
HaydenWelch
MVP Regular Contributor

I'd just use the CIM definition object, since all these properties can be set directly using dictionaries/CIM objects:

from typing import Any

from arcpy.management import MakeFeatureLayer
from arcpy.cim.CIMVectorLayers import CIMFeatureLayer
from arcpy.mp import ArcGISProject
from arcpy._mp import Layer, Map

def get_state(lyr: Layer) -> dict[str, Any]:
    layer_cim: CIMFeatureLayer = lyr.getDefinition('V3')
    states_to_save = [
        'snappable', 
        'selectable', 
        'visibility',
        'expanded',
        'labelVisibility',
    ]
    return {k:v for k, v in layer_cim.__dict__ if k in states_to_save}

def apply_state(lyr: Layer, state: dict[str, Any]) -> None:
    if not lyr.isFeatureLayer:
        return
    layer_cim: CIMFeatureLayer = lyr.getDefinition('V3')
    layer_cim.__dict__.update(state)
    lyr.setDefinition(layer_cim)

 

The first function will pull states from a layer and the second will apply those states to a layer. In your case, you can put these in a loop for the map:

...

def update_map_layers(mp: Map, state: dict[str, Any]) -> None:
    for layer in filter(lambda m: m.isFeatureLayer, mp.listLayers()):
        apply_state(layer, state)
        
def main():
    template_layer = MakeFeatureLayer(r'<path/to/template>.lyrx')[0]
    state = get_state(template_layer)
    project = ArcGISProject('<path/to/project>.aprx || CURRENT')
    mp = project.listMaps('<map_name>')[0]
    update_map_layers(mp, state)

if __name__ == '__main__':
    main()