Updating Data Source Path in Layers not updating

970
9
09-26-2011 11:14 AM
MikeMacRae
Frequent Contributor
Hello everyone,

I am trying to replace the workspace path or datasource path in a number of mxd's. I am not sure which one is supposed to work for my scenario. The layers in my map that I want to change, all have the same workspace:

Z:\ESRI\Templates\IOR_2010\TemplateFiles\TemplateFiles.gdb

Each layer is sourced to a feature class within that directory.

I want to resource to a new workspace:

Z:\Site\Sitename\D01_IF.gdb

The names of the feature classes are different in each gdb, but they contain the same data and structure. (ie The "SOILS" feature class in the old gbd is now named "SOILS_IF" in the new gbd.

So in other words, I want to change the datasource from:

Z:\ESRI\Templates\IOR_2010\TemplateFiles\TemplateFiles.gdb\SOILS

to:

Z:\Site\Sitename\D01_IF.gdb\SOILS_IF

I've been through the help menu for "Updating and fixing data sources" The scenario it gives for the lyr.replaceDataSource syntax, explains that you can change the source from a feature class that has been renamed in the same file gdb, but none of the scenarios offer a solution to resourcing to a new gdb with a feature class of a different name. I thought my code below would have done that, but it does not change the data source. It doesn't spit out an error message either. Can anyone suggest an issue with my code?

Thanks,
Mike

folderPath = r"Z:\ESRI\Figure_Sourcing\Figures\MapSourcingTest"
try:
    for filename in glob.glob(os.path.join(folderPath, "*.mxd")):
        fullpath = os.path.join(folderPath, filename)
        #print "Editing", filename
        mxd = arcpy.mapping.MapDocument(filename)

            for lyr in arcpy.mapping.ListLayers(mxd):

                if lyr.name == "Soil Map Unit":
                
                    print lyr.dataSource + "  Datesource"
                    lyr.replaceDataSource(r"Z:\Site\Sitename\D01_IF.gdb", "FILEGDB_WORKSPACE", r"SOILS_IF")          
                    
        mxd2.saveACopy(r"Z:\ESRI\Figure_Sourcing\Figures\TestFigs\IOR\MapSourcingTest\Test2.mxd")
Tags (2)
0 Kudos
9 Replies
JakeSkinner
Esri Esteemed Contributor
The problem may be that your not specifying the data frame.  Try the following below.  It will replace all feature classes within an MXD with its corresponding feature class in the other file geodatabase.

import arcpy, os, glob
from arcpy import mapping
folderPath = r"Z:\ESRI\Templates\IOR_2010\TemplateFiles\TemplateFiles.gdb\SOILS"

env.overwriteOutput = True

for filename in glob.glob(os.path.join(folderPath, "*.mxd")):
    fullpath = os.path.join(folderPath, filename)
    mxd = mapping.MapDocument(filename)
    for df in mapping.ListDataFrames(mxd, "*"):
                for lyr in mapping.ListLayers(mxd, "*", df):   
                    print lyr.name
                    new_name = lyr.name + "_IF"
                    try:
                       lyr.replaceDataSource(r"Z:\Site\Sitename\D01_IF.gdb\SOILS_IF", "FILEGDB_WORKSPACE", new_name)
                    except ValueError:
                       pass
                    print "Successfully updated layer"
    mxd.saveACopy(r"Z:\ESRI\Figure_Sourcing\Figures\TestFigs\IOR\MapSourcingTest\Test2.mxd")
del mxd
0 Kudos
StephanieWendel
Esri Contributor
Hi Mike,

I think you have one tiny thing wrong with the script, it's this line:

 mxd2.saveACopy(r"Z:\ESRI\Figure_Sourcing\Figures\TestFigs\IOR\MapSourcingTest\Test2.mxd")


Change this line to:
 mxd.saveACopy(r"Z:\ESRI\Figure_Sourcing\Figures\TestFigs\IOR\MapSourcingTest\Test2.mxd")

Remember you are still working on the mxd variable and there is no mxd2 in what you have setup here. I think this is the problem. I found this out by taking it out the Try/Except. That's the only bad part about Try/Except, you miss out on those exception messages. You may want to add the getmessage there to help future troubleshooting.

Once I fixed that line, I had no problem running your script through the Try/Except and getting it to work.

I hope that helps! :cool:
0 Kudos
MikeMacRae
Frequent Contributor
Hey Stephanie,

Thanks for the suggestion. I was actually using the variable mxd2 in my original script. When i copied it over to post on here, I edited that to be mxd for display purposes. Looks like I forgot to change that one. 🙂

Jake, I ran your script on my mxd and it still isn't changing the datasource. I set some print messages to give me the datasource before the replace method and then to print it out afterwards and it remains the same. I checked the map itself, and it hasn't changed there either.

I noticed you set folderPath to the original datasource. This should be a directory to the mxd's to which I want to interate through, so I believe my original folderPath is correct. Did you mean to set a workspace instead? Would this be useful?

Thanks,
Mike
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Sorry, that was a copy/paste error on my end.  Here is what it should be:

import arcpy, os, glob
from arcpy import mapping
folderPath = r"Z:\ESRI\Figure_Sourcing\Figures\MapSourcingTest"

env.overwriteOutput = True

for filename in glob.glob(os.path.join(folderPath, "*.mxd")):
    fullpath = os.path.join(folderPath, filename)
    mxd = mapping.MapDocument(filename)
    for df in mapping.ListDataFrames(mxd, "*"):
                for lyr in mapping.ListLayers(mxd, "*", df):   
                    print lyr.name
                    new_name = lyr.name + "_IF"
                    try:
                       lyr.replaceDataSource(r"Z:\Site\Sitename\D01_IF.gdb", "FILEGDB_WORKSPACE", new_name)
                    except ValueError:
                       pass
                    print "Successfully updated layer"
    mxd.saveACopy(r"Z:\ESRI\Figure_Sourcing\Figures\TestFigs\IOR\MapSourcingTest\Test2.mxd")
del mxd
0 Kudos
MikeMacRae
Frequent Contributor
Hey there,

I haven't had time to get back to this, but now I've been testing again. This function does not seem to work, no matter which way i approach it.

I set up a blank .mxd and added a polygon feature class called "Line" and then saved it as Test2.mxd. I used the lyr.replaceDataSource method to replace the line FC to another FC in the same .gdb called "Line_1". I set print messages before and after the update to show the original datasource and then to print the new datasource. The print messages indicate that the update was successful (see print mssage result below), but when I open the map and open the layer properties, under the Source tab, the datasource has not changed. It is still the original path.

Has anyone had issues with this? Does this method work the way I think it does? Am I doing something wrong?

Thanks,
Mike

mxd = arcpy.mapping.MapDocument(r"C:\GIS\Test2.mxd")
for df in arcpy.mapping.ListDataFrames(mxd, "*"):
    #print df.name
    for lyr in arcpy.mapping.ListLayers(mxd, "*", df):
        #print lyr.name
        if lyr.supports("DATASOURCE"):
            #print lyr.dataSource
            if lyr.dataSource == "C:\\GIS\\Test1.gdb\\Line":
                print lyr.name
                print lyr.dataSource #Print message to show the original datasource
                lyr.replaceDataSource("C:\\GIS\\Test1.gdb", "FILEGDB_WORKSPACE", "Line_1")
                print lyr.dataSource #Print message to show that the datasource has been replaced.
                
            
mxd.save()
del mxd


Here are my print messages:

Line
C:\GIS\Test1.gdb\Line
C:\GIS\Test1.gdb\Line_1
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Hi Mike,

I could not reproduce this behavior.  Try closing ArcMap, execute your script, and then re-open ArcMap and check the layer properties within the Test2.mxd.
0 Kudos
MikeMacRae
Frequent Contributor
Thanks for responding Jake. I've done that many times and the path still hasn't changed. I've also tried it on multiple computers and I keep coming up with the same result. I've contacted ESRI and they say that they cannot reproduce the issue either, so I'm at a wall with this one...
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Instead of using mxd.save, try saving a copy using mxd.saveACopy.  Maybe this could be some sort of write permissions error.
0 Kudos
MikeMacRae
Frequent Contributor
Hey Jake, thanks for your suggestions. I spent a couple weeks troubleshooting this issue and I finally discovered that a third party extension was causing the issue.

I have Xtools Pro installed on my computer. When they first released the version for ArcGIS 10, it was filled with bugs, but they released a new version that was supposed to fix these bugs. Apparently they didn't catch all of them, because I decided to uninstall the extension again and ran my script immediately afterwards and it now works perfectly.

I think I'm going to stay away from Xtools for a while as it has caused a lot of issues or me in the past.

Cheers,
Mike
0 Kudos