mxd.findAndReplaceWorkspacePaths Performance

09-28-2018 02:13 AM
New Contributor III

Hi there,

So I'm currently trying to transfer a series of MXDs from one organisation to another, the data is exactly the same but the datasource connection has changed.  Trying to use Python automate creating a copy of the MXDs with the new datasource, using the method above, but it has taken 20 minutes so far for an MXD with 1 layer in it (as a test).   The same is true of using the layer.findAndReplaceWorkspacePath method, it's just sitting there "running".  I've turned off the validation of the method but it's still not making any difference.  Should it be this slow?  Could I be doing something wrong?  Code snippet attached (removed sensitive info):

import arcpy
mxd = arcpy.mapping.MapDocument(r"mapDocument")
##mxd.findAndReplaceWorkspacePaths(r"oldPath", r"newPath",False)
for layer in arcpy.mapping.ListLayers(mxd):
   if layer.isGroupLayer == False:
      print layer.dataSource
      layer.findAndReplaceWorkspacePath(r"oldPath", r"newPath",False)

Is there any way to improve this performance because, quite frankly, if there isn't I'd be better off doing this manually!

Please note this is using ArcGIS Desktop 10.5.1 and Python 2.7, and no, I can't upgrade either (crappy hardware and company policies  )

0 Kudos
6 Replies
MVP Frequent Contributor

It should take more than a few seconds to change the paths and save the mxd.

Are you sure that oldpath & newpath are accessible from the machine?

New Contributor III

Hi Neil,

That's kind of the point, the new path is only available in the new location, and the old path is only available in the current location.  They are completely different networks and there's no way of accessing one from the other.  Is this what it's getting stuck on then?  I thought the point of setting validate to false was that it would change it regardless of whether the new path was correct or accessible?

Apologies, fairly new to Python (kind of the last man standing so having to do a whole bunch of things I haven't done previously!)

0 Kudos
MVP Frequent Contributor

(kind of the last man standing so having to do a whole bunch of things I haven't done previously!)

Haven't we all

Apologies, didn't notice the validate = False. 

0 Kudos
Esteemed Contributor

I think even if you do this manually it could take some time for ArcMap to open as it will try to find the SDE data that is not accessible. Below is a thread that talks about this behavior with SDE connections: 

New Contributor III

Hi Michael.

Thanks for the heads up, I would assume that there was a timeout on making connections that can be altered to speed up skipping with the knowledge that they are going to fail.  However the weird thing for me is it's not when I open the mxd in the code, or even when I access the layer array inside that, it's specifically when i try to do the find and replace method (which I assumed would essentially just be a string replace), but it's definitely trying to connect I think.  Have worked around this for now and got something working, will need to go back to the "new" office next week and see what happens there....

0 Kudos
New Contributor III

Hi All so just an update.  I managed to find a workaround to this (well, sort of).  Seeing as how the paths to the SDE connections (and the SDE connection names) are different on the source and target systems, I created a copy of the SDE connection on a local folder with the same name (but different connection details) on both systems.  That way when I access the MXD from the target system the SDE connection path hasn't changed and it seemed to be ok with this.  Then I simply run the Python to change the pointer from the local drive to the network share where the live SDE paths are stored and voila, all fixed .  Code I use is below (which works against all mxds in a folder):

import arcpy
from arcpy import env
sOldPath = r"<Temp SDE connection>"
sNewPath = r"<Final SDE connection>"

env.workspace = r"<MXD folder path>"
for file in arcpy.ListFiles("*.mxd"):
   mxd = arcpy.mapping.MapDocument(env.workspace + '/' + file)
   for layer in arcpy.mapping.ListLayers(mxd):
      if layer.supports("WORKSPACEPATH") == True:
            print "Original workspace: " + layer.workspacePath
            sSource = layer.workspacePath
            sSource = sSource.replace(sOldPath,sNewPath)
            print "New datasource (before): " + sSource
            print "New datasource (after): " + layer.workspacePath
         except Exception:
            e = sys.exc_info()[1]
   print mxd.filePath.replace('.mxd','_TMP.mxd')

Hope this helps anyone else who might be trying to do this!