Hello all,
I am using ArcGIS Pro 2.8.0 and Python 3.
I am trying to write a script to go through ArcGIS Pro projects in order to update connection properties of feature layers. Some of the features in the projects are sourced incorrectly. Those layers will be copied to the correct gdb (the path contained in the productsDict) and their source updated to that path. I am iterating through a nested dictionary, productsDict, which is structured as below.
productsDict = {project_1: {'APRX': '<absolute file path to .aprx>', 'GDB': '<absolute file path to .gdb>'}, project_2: {'APRX': '<absolute file path to .aprx>', 'GDB': '<absolute file path to .gdb>'}, etc.}}
The desired flow of the script is below:
-create an object for each aprx
-iterate through all maps in current aprx
-iterate through feature layers in each map
-compare the current source of each layer, this checks if it's sourced to the correct gdb the
-copy feature layer to correct gdb
-update the source in the layer's connection properties
The problem that I am experiencing is with the layer.updateConnectionProperties call. When I open the project manually, it shows that the source was changed, however, it is now broken. When I manually change the source to the same location, it works. For some reason Arc is not recognizing the projects gdb as a valid data source which is why I pass "validate=False".
If any other information is needed let me know. Thank you in advance!
for key, value in productsDict.items():
#returns absolute file path for .aprx
try:
a = productsDict[key]['APRX']
except KeyError:
continue
#create map object for each .aprx if maps exist
if a:
try:
aprx = arcpy.mp.ArcGISProject(a)
#set default .gdb
aprx.defaultGeodatabase = productsDict[key]['GDB']
except OSError:
continue
#return list of maps in current .aprx
maps = aprx.listMaps()
for m in maps:
for layer in m.listLayers():
if layer.isFeatureLayer == True:
#return dictionary of layer connection properties
lcp = layer.connectionProperties
#compares source path, only change if data source to wrong .gdb
if productsDict[key]['GDB'] != lcp['connection_info']['database']:
try:
#copy layers from original .gdb to correct .gdb
arcpy.FeatureClassToFeatureClass_conversion(layer, productsDict[key]['GDB'], str(layer))
except Exception as e:
pass
try:
#change connection path of layer to correct .gdb
dataGDB = productsDict[key]['GDB']
lcp['connection_info']['database'] = f'{dataGDB}\\' + str(layer)
#update layer connection in connection properties dictionary
layer.updateConnectionProperties(layer.connectionProperties, lcp, validate=False)
except Exception as e:
continue
aprx.save()
I've had some strange behavior with changing data sources of layers with 3.x and it came down to creating a new connectionProperties object and replacing the whole connectionProperties object rather than updating the individual property. There is another thread that has some good sample code that you can probably pull from for this method. I'll try to find it and update this post when I do but it may be worth a try in your circumstance.