UPDATE: This woks fine for updating the source to Shapefiles but not for SDE feature classes!
I am trying to use replaceDataSource by iterating through multiple map documents. My script updates the first map document but always fails on the second. So if I have map1.mxd, map2.mxd and map3.mxd it updates dataSources in map1 and fails on map2. Even if I put map2 through first (map1 2nd and map3 3rd) it will still fail on the 2nd iteration, so map1 fails in this instance.
I am updating the source to SDE. The input csv is the output from another script that gets unique broken datasources. I then add a second column that matches the broken datasource to a new one
import arcpy, csv, os
import arcpy.mapping as m
def updateDataSource(datapath, broken_lyr):
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 "\n"
print workspace_path
print workspace_type
print dataset_name
print "\n"
if workspace_path:
broken_lyr.replaceDataSource(workspace_path, workspace_type, dataset_name, True)
else:
print "Failed for {0} \n workspace is not FILEGDB, SDE, or SHAPEFILE".format(broken_lyr.name)
input_csv = r"C:\Users\glen.bambrick\Documents\csv\broken_links_20180523.csv"
input_folder = r"C:\Users\glen.bambrick\Documents\mxd"
broken_dict = {}
broken_mxd_list = []
with open(input_csv, 'rb') as read_csv:
reader = csv.reader(read_csv)
next(reader, None)
for row in reader:
if row:
broken_dict[row[0]] = row[1]
broken_mxd_list.append(row[3])
mxd_set = set([])
for value in broken_mxd_list:
for item in value.split(", "):
mxd_set.add("{0}\\{1}".format(input_folder, item))
for key, value in broken_dict.iteritems():
print key, value
print "\n"
print mxd_set
for mapdoc in mxd_set:
print "\n"
print mapdoc
mxd = m.MapDocument(mapdoc)
list_broken = m.ListBrokenDataSources(mxd)
if len(list_broken) == 0:
continue
else:
for broken in list_broken:
if broken.supports("DATASOURCE") and broken_dict[broken.dataSource]:
print "Updating: {0}".format(broken.dataSource)
print "\tTo: {0}".format(broken_dict[broken.dataSource])
updateDataSource(broken_dict[broken.dataSource], broken)
mxd.save()
del mxd
The output and the error. As you can see the same parameters are going in but it always fails on the first replaceDataSource() of the second iteration no matter what map document it is. If there is one mxd in the list it will do it just fine, but I want to loop through hundreds eventually.
C:\Users\user1\AppData\Roaming\ESRI\Desktop10.4\ArcCatalog\N6.sde\JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition_1 Database Connections\Connection to GALSQL01.sde\JN233985_GCOB.DBO.GCOB_03_Environmental\JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition
C:\Users\user2\AppData\Roaming\ESRI\Desktop10.4\ArcCatalog\Connection to GALSQL01.sde\JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition_1 Database Connections\Connection to GALSQL01.sde\JN233985_GCOB.DBO.GCOB_03_Environmental\JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition
set(['C:\\Users\\glen.bambrick\\Documents\\mxd\\map2.mxd', 'C:\\Users\\glen.bambrick\\Documents\\mxd\\map1.mxd'])
C:\Users\glen.bambrick\Documents\mxd\map2.mxd
Updating: C:\Users\user1\AppData\Roaming\ESRI\Desktop10.4\ArcCatalog\N6.sde\JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition_1
To: Database Connections\Connection to GALSQL01.sde\JN233985_GCOB.DBO.GCOB_03_Environmental\JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition
Database Connections\Connection to GALSQL01.sde
SDE_WORKSPACE
JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition
Updating: C:\Users\user2\AppData\Roaming\ESRI\Desktop10.4\ArcCatalog\Connection to GALSQL01.sde\JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition_1
To: Database Connections\Connection to GALSQL01.sde\JN233985_GCOB.DBO.GCOB_03_Environmental\JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition
Database Connections\Connection to GALSQL01.sde
SDE_WORKSPACE
JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition
C:\Users\glen.bambrick\Documents\mxd\map1.mxd
Updating: C:\Users\user1\AppData\Roaming\ESRI\Desktop10.4\ArcCatalog\N6.sde\JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition_1
To: Database Connections\Connection to GALSQL01.sde\JN233985_GCOB.DBO.GCOB_03_Environmental\JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition
Database Connections\Connection to GALSQL01.sde
SDE_WORKSPACE
JN233985_GCOB.DBO.GCOB_03391_Beneficial_Deposition
Traceback (most recent call last):
File "C:\Users\glen.bambrick\Desktop\test.py", line 65, in <module>
updateDataSource(broken_dict[broken.dataSource], broken)
File "C:\Users\glen.bambrick\Desktop\test.py", line 23, in updateDataSource
broken_lyr.replaceDataSource(workspace_path, workspace_type, dataset_name, True)
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