Changing data source of .lyr files

6895
6
Jump to solution
01-27-2015 09:31 AM
TychoGranville
Occasional Contributor II

I've got 65 layer files (both normal and group ones) that need their data sources changed. I got the following script to work for MXDs (which is good since there are several hundred):

HomerString = [list of mxds with paths]
for bob in HomerString:
    mxd = arcpy.mapping.MapDocument(bob)
 mxd.findAndReplaceWorkspacePaths("WC-HOMER", "WC-HOMERB")
    NewString = bob.replace(r'\\WC-HOMER', r'\\WC-HOMERB')
    mxd.saveACopy(NewString)
    del mxd

But I cannot figure out any variation of it that will work for .lyr files

(and I did look at code snippets, help documents, and Google before posting here)

Any ideas or solutions out there?

Thanks,

Tycho

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

Is something like this what you are after:

layers = [list of layers with paths]
for layer_path in layers:
    lyr = arcpy.mapping.Layer(layer_path)
    lyr.findAndReplaceWorkspacePath(...)
    lyr.saveACopy(...)

View solution in original post

0 Kudos
6 Replies
JoshuaBixby
MVP Esteemed Contributor

Is something like this what you are after:

layers = [list of layers with paths]
for layer_path in layers:
    lyr = arcpy.mapping.Layer(layer_path)
    lyr.findAndReplaceWorkspacePath(...)
    lyr.saveACopy(...)
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Unlike the MXD version of findandreplace, which ends in paths, plural, the LYR version of findandreplace end in path, singular.  I am not sure whether the LYR version recursively searches or not, like the MXD version.  If not, you can add some code to loop through all the layers in a layer file:

layer_paths = [list of layers with paths]
for layer_path in layer_paths:
    layer = arcpy.mapping.Layer(layer_path)
    for lyr in arcpy.mapping.ListLayers(lyr):
        lyr.findAndReplaceWorkspacePath(...)
    layer.saveACopy(...)
0 Kudos
TychoGranville
Occasional Contributor II

I tried variations of that for the last couple of days. I got rid of all the nifty for-in loops and lists. It's down to this -

#Modules
import arcpy
lyr = arcpy.mapping.Layer(r"\\WC-HOMER\Shared\GIS\2N15E.lyr")
lyr.findAndReplaceWorkspacePath("WC-HOMER", "WC-HOMERB")
lyr.saveACopy(r"\\WC-HOMERB\Shared\GIS\2N15E.lyr")
del lyr

If I don't comment out line 4 I get the error

ValueError: Layer: Unexpected error

I've tried using various strings for line 4, including (r"\\WC-HOMER", r"\\WC-HOMERB"). At this point I'm almost out of hair to pull...

0 Kudos
XanderBakker
Esri Esteemed Contributor

Did you try the alternative:

Layer.replaceDataSource(workspace_path, workspace_type, dataset_name, {validate})

ArcGIS Help (10.2, 10.2.1, and 10.2.2)

JoshuaBixby
MVP Esteemed Contributor

That error with findAndReplaceWorkspacePath is common when you are trying to not just replace the workspace path but also the workspace type.  Are you switching from a personal geodatabases to a file geodatabases?  If you are switching workspace types as well, then you need to use replaceDataSource as Xander Bakker‌ suggests.

Also, if you are going to be coming across group layers or layers with lots of different data sources, it is good to use the layer.supports method to check the layer supports a data source property.

TychoGranville
Occasional Contributor II

Thanks for your help, guys. Hopefully this will help the next newbie that stumbles into this.

It looks like i was formatting the findAndReplaceWorkspacePath incorrectly. It appears that just changing the server name is not enough; you have to have at least part of the old and new paths as well. As all the data and directory structure was copied onto the new server I thought all I needed was to substitute the new server name for the old one (so from Homer to HomerB in my case). As soon as I changed the string to a real path -

layer.findAndReplaceWorkspacePath(r"\\WC-HOMER\Shared\GIS", r"\\WC-HOMERB\Shared\GIS")

- everything works as advertised

0 Kudos