0

The documentation for ArcGIS Pro for updateConnectionProperties https://pro.arcgis.com/en/pro-app/2.8/arcpy/mapping/updatingandfixingdatasources.htm#ESRI_SECTION1_18159CA0096044608B406CA068794E30 has an example how to update a file path connection for a folder that was renamed, how do I do it for a folder that was removed.

For example, the old file path that is broken is:

C:\Data\Archived Projects\Work.gdb

The good file path is: C:\Data\Work.gdb

I tried the following code

aprx.updateConnectionProperties('Archived Projects', '')

but it doesn't update the file path. For some reason the following isn't working either for this specific project

aprx.updateConnectionProperties(r'C:\Data\Archived Projects\Work.gdb', r'C:\Data\Work.gdb'

I obviously have more code, but this is the only relevant part. I can print the list of broken data sources, try to fix them, and then save the APRX, but in the end no data sources are fixed.

I admit the project I am working in is very old and screwy in general. I am able to use the updateConnectionProperties to fix some broken data links but not others, specifically related to data sources that ArcGIS Pro thinks are in the the "Archived Projects" folder, which no longer exists.

I need to fix all the data links in this old project, and there are hundreds, I need to do it with Python, not one by one.

2 Answers 2

0

You need to populate an dictionary prior to using the updateConnectionProperties of your layer:

    origConnPropDict = lyr.connectionProperties
    newConnPropDict = {'connection_info': {
               'database': r'C:\Data\Work.gdb'},
               'dataset': <your feature class name>,
               'workspace_factory': 'File Geodatabase'}
    lyr.updateConnectionProperties(origConnPropDict,
                                   newConnPropDict)
2
  • I know the .updateConnectionProperties is able to run without a dictionary if you are just changing the data source location of your feature class? import arcpy aprx = arcpy.mp.ArcGISProject(r'C:\Projects\YosemiteNP\Yosemite.aprx') aprx.updateConnectionProperties(r'C:\Projects\YosemiteNP\Data\Yosemite.gdb', r'C:\Projects\YosemiteNP\Vector_Data\Yosemite.gdb') aprx.saveACopy(r"C:\Projects\YosemiteNP\YosemiteNew.aprx") This is an example from ESRI. Can you please elaborate why dictionary is necessary in this case?
    – sparky
    May 27, 2022 at 0:35
  • It's hard to elaborate without more details in your original question. I tried to fill in the gaps between what you presented and a code snippet as best I could when writing this answer.
    – PolyGeo
    May 27, 2022 at 2:56
0

At a minimum, the documentation is incomplete for this specific type of situation, and someone could even argue there is a software defect involved (not that it is important enough to me to log a defect).

According to Updating and fixing data sources—ArcGIS Pro | Documentation,

If an empty string or None is used in current_connection_info, all connection properties will be replaced with the new_workspace_info, depending on the value of the validate parameter.

The catch is, Esri doesn't state what happens if the new_connection_info is an empty string or None. In reality, what happens is nothing. No documentation, no error, and no change; definitely leaves plenty of room for improvement.

The "safe" ways to address this situation are to either include the full path or include the leftmost part of the path until the change occurs, for example:

# change workspace from C:\folder\subfolder\fgdb.gdb to C:\folder\fgdb.gdb

# using full path
aprx.updateConnectionProperties(
    r"C:\folder\subfolder\fgdb.gdb",
    r"C:\folder\fgdb.gdb"
)

# using leftmost part of path until change
aprx.updateConnectionProperties(
    r"C:\folder\subfolder",
    r"C:\folder"
)

I realize this wasn't working for the OP, but this commonly works, so something else was happening with OP beyond the attempt to use an empty string

There are a couple other options to make this work that rely on the fact that ArcGIS Pro normalizes the path before actually updating it. I wouldn't necessarily recommend these, but they are worth sharing for awareness.

Looking at path normalization with regular Python str.replace():

>>> import os
>>>
>>> fgdb_path = r"C:\folder\subfolder\fgdb.gdb"
>>> os.path.normpath(fgdb_path)
'C:\\folder\\subfolder\\fgdb.gdb'
>>>
>>> os.path.normpath(fgdb_path.replace(r"subfolder", r""))
'C:\\folder\\fgdb.gdb'

If ArcGISProject.updateConnectionProperties() accepted empty strings for new_connection_info, we can see it would normalize just fine to the desired path, but we know this option is off the table.

There are other non-empty strings that can be used and normalized to the desired path if one understands path-naming conventions.

>>> import os
>>>
>>> fgdb_path = r"C:\folder\subfolder\fgdb.gdb"
>>> os.path.normpath(fgdb_path.replace(r"subfolder", r"."))
'C:\\folder\\fgdb.gdb'
>>>
>>> os.path.normpath(fgdb_path.replace(r"subfolder", r"\\"))
'C:\\folder\\fgdb.gdb'
>>>

The first replaces the subfolder name with a single dot/period, which is a token or symbol representing the current directory name. During path normalization, the current directory tokens are removed. The second replaces the folder name with a backslash, which creates an extraneous path delimiter. During path normalization, extraneous path delimiters are also removed.

This behavior of path normalization can be used with ArcGISProject.updateConnectionProperties() as long as the current_connection_info string represents a complete name of a path sub-component.

# change workspace from C:\folder\subfolder\fgdb.gdb to C:\folder\fgdb.gdb

# using current working directory token
aprx.updateConnectionProperties(r"subfolder", r".")

# using extraneous path delimiter 
aprx.updateConnectionProperties(r"subfolder", r"\\")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.