replace data source for layer files in a directory

3286
3
08-23-2011 12:29 PM
ShannonLadd
New Contributor
I am currently trying to complete a script that will update the data source for layer files in a user specified directory.

I am working with SDE data and am trying to update the location of multiple SDE geodatabases. I have a text file that stores the server name and new path (as such: server, new path) so that I can use layer properties to identify which data source each layer should be updated to based on server. I am not using the old path to identify the new path because the layer files have been created from individual database connections with nonstandardized names, so to get around having to identify 100s of current paths to determine the new path to update to, the script uses the if lyr.supports("SERVICEPROPERTIES"): to identify the server name.

Where I am running into an issue is with the lyr.save(). I get the following error:

Traceback (most recent call last):
  File "C:\My_REG\Python\Broken Links\DirectoryLayerRepair\Directory_Replace_Layer_Workspace_Path.py", line 48, in <module>
    lyr.save()
  File "C:\Program Files\ArcGIS\Desktop10.0\arcpy\arcpy\utils.py", line 181, in fn_
    return fn(*args, **kw)
  File "C:\Program Files\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\mixins.py", line 272, in save
    self._arc_object.save(layer_file) # SaveToLayerFile(self._arc_object, layer_file)
ValueError: Layer: Unexpected error

I can get the script to execute if I use the lyr.saveACopy(), until it encounters a layer in a group layer file. So my question is, can I get the script to work with the lyr.save() or how do I handle working with group layers and updating the individual layers and the lyr.saveACopy()?

import os
import sys
import arcpy
import arcpy.mapping as mapping
import string

rootdir = ("S:\\Data_Collection")#arcpy.GetParameterAsText(0)

inData = ("P:\\Scripts\\Regulation\\Repair_Broken_Links\\Find and Replace Workspace Paths.txt")
readFile = open(inData, "r")

for line in readFile:
    word = line.split(",")
    old_connection = word[0].strip()
    new_connection = word[1].strip()
    lth = len(old_connection)
   
    for root, subFolders, files in os.walk(rootdir):
        for f in files:
            fullpath = os.path.join(root, f)
            basename, extension = os.path.splitext(fullpath)
            if extension.lower() == ".lyr":
                lyrFile = mapping.Layer(fullpath)
                for lyr in mapping.ListLayers(lyrFile):
                    if lyr.isFeatureLayer == True:
                        if lyr.supports("SERVICEPROPERTIES"):
                            servProp = lyr.serviceProperties
                            if lyr.serviceProperties["ServiceType"] != "SDE":
                                connection = servProp.get('Server', 'N/A')
                                current_connection = string.lower(connection)
                            else:
                                connection = servProp.get('Server', 'N/A')
                                current_connection = string.lower(connection)
                        if current_connection[:lth] == old_connection:
                            lyr.replaceDataSource(new_connection, "SDE_WORKSPACE", "", False)
                            print str(lyr) + ' successfully updated to ' + str(new_connection)
                            lyr.save()
                            #lyr.saveACopy(text to save a new copy)
                        else:
                            print 'fail'
                    else:
                        pass

readFile.close()
del lyr
del lyrFile
Tags (2)
3 Replies
JoelCalhoun
New Contributor III
Does replaceDataSource require a lyr save?  I have a script that seems to work without using a save.  Try running the script without saving and see if the change is maintained.

Good Luck!
0 Kudos
ShannonLadd
New Contributor
The script ran without error, but the changes were not maintained without the save.

I hadn't paid enough attention to realize I lost my indentation in my original post. I have attached the scrpit.
0 Kudos
RaphaelR
Occasional Contributor II
if it´s the group layers giving you problems you could try getting only the layernames from the layerlist
for example:
# get the list of layers with mapping.ListLayers
lyrlist = ["layer1", "GL1\GL2\layer2", "GL1\layer3"]

# get just the layer´s names with a list comprehension
lyrnames = [l.split("\\")[-1] for l in lyrlist]
0 Kudos