Trying to update data sources across multiple map documents. The first iteration works but fails on the second no mater the order.

The input csv is the output from another script that lists unique broken datasources across the map documents. I then fill in a second column for new links.

If I run on an individual map document it works fine even for the one that failed when second in the loop.

I tested on two map documents that have the same broken data links and still it fails on the second one.

In this instance I am only working with data on SDE.

import arcpy, csv, os
import arcpy.mapping as m

# assess whether shapefile, geodatabase, or sde
# and get parameters for replaceDataSource() 
def updateDataSource(datapath, broken_lyr, workspace_path=None, workspace_type=None, dataset_name=None):
    if datapath.endswith(".shp"):
        workspace_path = datapath.rsplit("\\", 1)[0]
        workspace_type = "SHAPEFILE_WORKSPACE"
        dataset_name = datapath.rsplit("\\", 1)[-1][0:-4]
    elif datapath.find(".sde") != -1:
        workspace_path = datapath.rsplit(".sde", 1)[0] + ".sde"
        workspace_type = "SDE_WORKSPACE"
        dataset_name = datapath.rsplit("\\")[-1]
    elif datapath.find(".gdb") != -1:
        workspace_path = datapath.rsplit(".gdb", 1)[0] + ".gdb"
        workspace_type = "FILEGDB_WORKSPACE"
        dataset_name = datapath.rsplit(".gdb\\")[-1]
        print "Neither SHP, GDB, or SDE"

    if workspace_path:
        broken_lyr.replaceDataSource(workspace_path, workspace_type, dataset_name)

input_csv = r"C:\Users\glen.bambrick\Documents\csv\broken_links_20180523.csv"
input_folder = r"C:\Users\glen.bambrick\Documents\mxd"

# store data from csv in here
# key: broken data link
# value: new data link
broken_dict = {}

with open(input_csv, 'rb') as read_csv:
    reader = csv.reader(read_csv)
    next(reader, None)
    for row in reader:
        broken_dict[row[0]] = row[1]

# list map documents from folder provided
mxd_files = [mxd_file for mxd_file in os.listdir(input_folder) if mxd_file.endswith(".mxd")]

# iterate through map documents
for mapdoc in mxd_files:
    print mapdoc
    mxd = m.MapDocument("{0}\\{1}".format(input_folder, mapdoc))
    # get a list of broken links
    list_broken = m.ListBrokenDataSources(mxd)
    if len(list_broken) == 0:
        for broken in list_broken:
            # if the link is in the dictionary then update it
            if broken_dict[broken.dataSource]:
                updateDataSource(broken_dict[broken.dataSource], broken)


This is the error I get

Traceback (most recent call last):
  File "C:/Users/glen.bambrick/Desktop/test.py", line 45, in <module>
    updateDataSource(broken_dict[broken.dataSource], broken)
  File "C:/Users/glen.bambrick/Desktop/test.py", line 19, in updateDataSource
    broken_lyr.replaceDataSource(workspace_path, workspace_type, dataset_name)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.5\ArcPy\arcpy\utils.py", line 182, in fn_
    return fn(*args, **kw)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.5\ArcPy\arcpy\_mapping.py", line 682, in replaceDataSource
    return convertArcObjectToPythonObject(self._arc_object.replaceDataSource(*gp_fixargs((workspace_path, workspace_type, dataset_name, validate), True)))
ValueError: Layer: Unexpected error

As said already it works perfect on the first iteration and when run one at a time but I cannot get it to run through multiple like it should. Any ideas?

  • "it works perfect on the first iteration..." The first iteration of a map or the first iteration of a broken data source? – Tom May 24 '18 at 14:52
  • @Tom the first iteration of a map that has multiple broken datasources the same as the second map, but fails at the first attempt to update in the second map. – Clubdebambos May 24 '18 at 14:59
  • Try adding a print statement right before broken_lyr.replaceDataSource. Make it: print(workspace_path, workspace_type, dataset_name), so that you can see what's different across the two iterations. – Tom May 24 '18 at 15:39
  • @Tom tried that and the inputs are the same on map2 as in map1. Even if I make a copy of map1 and run it only on essentially the same but renamed mxd twice (so map1a, map1b) it fails at the first update in the second iteration. – Clubdebambos May 24 '18 at 15:42
  • Unless you've got the map open in ArcMap and a lock is preventing this, then I don't know. Make sure everything else is closed (including ArcCatalog). And perhaps try del mxd right after mxd.save(). If that doesn't work, I have no idea what might be going on. Sorry. – Tom May 24 '18 at 19:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.