replaceDataSource in layer file (not mxd)

3113
12
Jump to solution
05-08-2013 08:16 AM
BrianMaier
New Contributor II
My world: Win7, ArcGIS 10.0  SP1, Python 2.6.5

I am attempting to update a group layer file with new data source locations (FGDB moved from one location to another location). I get no errors running this code, but the new file locations are not updated in the layer file.  Most of the discussions in this forum (related to this issue) are related to using an mxd, but in my case, I want to update a layer file (*.lyr). 


  • Have verified that the paths are correct (via print statements).

  • Have verified that i am updating feature classes and that they support the DATASOURCE property

  • Have also tried saving the .lyr file using "arcpy.mapping.Layer(inLayerFile).saveACopy("newfilename")"

  • I have tried findAndReplaceWorkspacePath with no success.

  • Have tried converting newPath variable to unicode - again no success.


Any help greatly appreciated!

# xModifyDataLocationsInlayerFiles.py  import sys, os import arcpy  outFolder = r"C:\Projects\CoreData\GeoName" newFolder = r"C:\projects\testmove\test2\GeoName"  inLayerFile = r"C:\projects\testmove\test2\GeoName\LayerFiles\AG10\BaseInfo.lyr"  for lyr in arcpy.mapping.Layer(inLayerFile):   pout = lyr.isFeatureLayer   if pout == True:     if lyr.supports("DATASOURCE"):       currWSPath = str(lyr.workspacePath)       scol = str.upper(currWSPath).find('GEONAME')       scol = scol + len('GEONAME') + 1       newPath = newFolder + os.sep + currWSPath[scol:]       print lyr.name + " | Path: " + newPath + " | DSN: " + lyr.datasetName       lyr.replaceDataSource(unicode(newPath), 'FILEGDB_WORKSPACE', lyr.datasetName, True)     else:       print "Layer " + lyr.name + " does not support datasource changes"   else:     pass
Tags (2)
0 Kudos
12 Replies
MichaelVolz
Esteemed Contributor
Brian:

A slightly modified version of Jeff's script worked for me where I switched out findAndReplaceWorkspacePath with replaceDataSource to get a group layer to have its connection properties updated.

You might want to simplify your script to get it to work and then attempt to rebuild it close to its existing structure.
0 Kudos
BrianMaier
New Contributor II
Thank you Jeff. Your code references objects "lyr1" and "lyr2" but these are not defined in your script. At first I assumed these would be "fullLyr" and "relLyr", but the function ListLayers doesn't support layer files, it seems to only support map documents. I can get this to work inside a map document, but I was hoping to avoid using an MXD if possible.

However, I need to get moving beyond this, so my solution is simply to open a blank mxd, add my layer file, update the source using .findAndReplaceWorkspacePath, then save the top layer of the layers in the MXD. Since I control the creation of the  layer file to begin with I know that I can save this top layer and I get the expected result.  Then I just delete the temporary mxd file.

Thank you all for your help.  My final code (which works properly) is posted here, but sadly I did have to resort to using an MXD:

import arcpy  outFolder = r"C:\Projects\CoreData\GeoName" newFolder = r"\\silver\projects\SpatialData_Core\GeoName"  inLayerFile = r"C:\Projects\testmove\test2\GeoName\LayerFiles\AG10\BaseInfo.lyr" outLayerFile = r"\\silver\projects\SpatialData_Core\GeoName\LayerFiles\AG10\BaseInfo_updated.lyr" inMXDFile = r"C:\Projects\CoreData\GeoName\LayerFiles\AG10\BaseInfo.mxd" outMXDFile = r"\\silver\projects\SpatialData_Core\GeoName\LayerFiles\AG10\BaseInfo_updated.mxd"  if arcpy.Exists(outMXDFile):     arcpy.Delete_management(outMXDFile)      if arcpy.Exists(outLayerFile):     arcpy.Delete_management(outLayerFile)  mxd = arcpy.mapping.MapDocument(inMXDFile) mxd.findAndReplaceWorkspacePaths(outFolder,newFolder, False) mxd.saveACopy(outMXDFile)  del mxd mxd = arcpy.mapping.MapDocument(outMXDFile) df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0] lyr = arcpy.mapping.ListLayers(mxd, "", df)[0] lyr.saveACopy(outLayerFile)  if arcpy.Exists(outMXDFile):     arcpy.Delete_management(outMXDFile)  print "Finished creating new Layer file: " + outLayerFile
0 Kudos
JeffBarrette
Esri Regular Contributor
I'm sorry Brian.  I tried to clean up the variable names so they would be more meaningful.  I should stop doing that after I have the code working.  Here is the corrected code.  ListLayers does work on layer files.  Think of a layerfile as being a container of layers, just like an MXD.  In many cases a layer file may only be a single layer but when you have group layers, it can be many layers.

import arcpy
fullLyr = arcpy.mapping.Layer(r"C:\Temp\FullPath.lyr")
lyrs = arcpy.mapping.ListLayers(fullLyr)
for lyr in lyrs:
  if lyr.supports("DATASOURCE"):
    lyr.findAndReplaceWorkspacePath(r"C:\Temp", r"C:\Active\ArcPY\ScrumWorks\Data")
fullLyr.saveACopy(r"C:\Temp\FullPath2.lyr")

rellLyr = arcpy.mapping.Layer(r"C:\Temp\RelPath.lyr")
lyrs = arcpy.mapping.ListLayers(rellLyr)
for lyr in lyrs:
  if lyr.supports("DATASOURCE"):
    lyr.findAndReplaceWorkspacePath(r"C:\Temp", r"C:\Active\ArcPY\ScrumWorks\Data")
relLyr.saveACopy(r"C:\Temp\RelPath2.lyr")


I hope this helps you,
Jeff
0 Kudos