We are changing our production server to have a prefix of 'HV'. I have a folder of MXDs I would like to update to the new server, but I am missing something from my code below. I got my start from https://gist.github.com/davehorsey/d8892b150e61d2e03617.
import arcpy, os
path = r"C:\layouts"
for fileName in os.listdir (path):
basename, extension = os.path.splitext(fileName)
# select MXD files that do NOT begin with "Copy_of_" - this
# prevents the script from updating files that have already been updated
if (extension == ".mxd") and (fileName[:8] != "Copy_of_"):
fullPath = os.path.join(path, fileName)
mxd = arcpy.mapping.MapDocument(fullPath)
print fullPath
# update data sources
mxd.findAndReplaceWorkspacePaths("Database Connections\\Server Database NT Auth.sde", "Database Connections\\HV_Server Database NT Auth.sde")
print "\tUpdated: SDE data sources"
# check for broken links
brknList = arcpy.mapping.ListBrokenDataSources(mxd)
for brknItem in brknList:
print "\tCheck: " + brknItem.name + " data source broken"
if not brknList:
print "\tCheck: no broken data sources"
# save a copy of the MXD
saveACopy_filename = "Copy_of_" + fileName
saveACopy_fullpath = os.path.join(path, saveACopy_filename)
mxd.saveACopy(saveACopy_fullpath)
print "\tSaved: " + saveACopy_filename
del mxd
# delete the original MXD
arcpy.Delete_management(fullPath)
print "\tDeleted: " + fullPath
Solved! Go to Solution.
I haven't test, but you could try the following:
import arcpy, os
from arcpy import env
from arcpy import mapping
# Parent directory to MXDs. Script will iterate through Child directories
env.workspace = r"D:\Temp\Python\MXDs"
# New Enterprise Geodatabase
newDataSource1 = r"Database Connections\DBO@GIS.sde"
newDataSource2 = r"Database Connections\USER1@GIS.sde"
newDataSource3 = r"Database Connections\USER2@GIS.sde"
env.overwriteOutput = True
for (path, dirs, files) in os.walk(env.workspace):
for file in files:
if ".mxd" in file.lower():
mxd = os.path.join(path, file)
print(mxd + " is being processed")
mxd = mapping.MapDocument(mxd)
for df in mapping.ListDataFrames(mxd, "*"):
for lyr in mapping.ListLayers(mxd, "*", df):
try:
if lyr.supports("DATASOURCE"):
if lyr.serviceProperties['Database']:
print("\tUpdating " + str(lyr))
try:
lyr.replaceDataSource(newDataSource, "SDE_WORKSPACE", "")
print("\tSuccessfully updated data source")
except:
try:
lyr.replaceDataSource(newDataSource2, "SDE_WORKSPACE", "")
print("\tSuccessfully updated data source")
except:
try:
lyr.replaceDataSource(newDataSource3, "SDE_WORKSPACE", "")
print("\tSuccessfully updated data source")
except:
print("\tCould not update " + str(lyr))
pass
except AttributeError:
pass
mxd.save()
del mxd
Hi Brian,
I've had success with the following script. It will iterate through a directory and child directories and update all database connections with the one specified in the newDataSource variable.
import arcpy, os
from arcpy import env
from arcpy import mapping
# Parent directory to MXDs. Script will iterate through Child directories
env.workspace = r"D:\Temp\Python\MXDs"
# New Enterprise Geodatabase
newDataSource = r"Database Connections\DBO@GIS.sde"
env.overwriteOutput = True
for (path, dirs, files) in os.walk(env.workspace):
for file in files:
if ".mxd" in file.lower():
mxd = os.path.join(path, file)
print(mxd + " is being processed")
mxd = mapping.MapDocument(mxd)
for df in mapping.ListDataFrames(mxd, "*"):
for lyr in mapping.ListLayers(mxd, "*", df):
try:
if lyr.supports("DATASOURCE"):
if lyr.serviceProperties['Database']:
print("\tUpdating " + str(lyr))
lyr.replaceDataSource(newDataSource, "SDE_WORKSPACE", "")
print("\tSuccessfully updated data source")
except AttributeError:
pass
mxd.save()
del mxd
Thanks, Jake,
That worked for one data source, unfortunately, I have 3 databases referenced in the MXDs. Is there an 'if else' statement to point it towards the next database if the first one does not work?
I should say if the first database connection does not contain the layer to reference to, but the layer is in the next database.
I haven't test, but you could try the following:
import arcpy, os
from arcpy import env
from arcpy import mapping
# Parent directory to MXDs. Script will iterate through Child directories
env.workspace = r"D:\Temp\Python\MXDs"
# New Enterprise Geodatabase
newDataSource1 = r"Database Connections\DBO@GIS.sde"
newDataSource2 = r"Database Connections\USER1@GIS.sde"
newDataSource3 = r"Database Connections\USER2@GIS.sde"
env.overwriteOutput = True
for (path, dirs, files) in os.walk(env.workspace):
for file in files:
if ".mxd" in file.lower():
mxd = os.path.join(path, file)
print(mxd + " is being processed")
mxd = mapping.MapDocument(mxd)
for df in mapping.ListDataFrames(mxd, "*"):
for lyr in mapping.ListLayers(mxd, "*", df):
try:
if lyr.supports("DATASOURCE"):
if lyr.serviceProperties['Database']:
print("\tUpdating " + str(lyr))
try:
lyr.replaceDataSource(newDataSource, "SDE_WORKSPACE", "")
print("\tSuccessfully updated data source")
except:
try:
lyr.replaceDataSource(newDataSource2, "SDE_WORKSPACE", "")
print("\tSuccessfully updated data source")
except:
try:
lyr.replaceDataSource(newDataSource3, "SDE_WORKSPACE", "")
print("\tSuccessfully updated data source")
except:
print("\tCould not update " + str(lyr))
pass
except AttributeError:
pass
mxd.save()
del mxd
Thanks Jake,
You saved me a bunch of time!