Skip to main content
edited tags
Link
Midavalo
  • 29.9k
  • 11
  • 51
  • 105
Source Link
grego
  • 1.1k
  • 7
  • 19

.replaceDataSource() results in ValueError: Layer: Unexpected error

I am replacing data sources for any of my layer files (.lyrs) that have a data source in L: . My code (in the Step 1 section) looks through each object in the ListLayers list first, determining which objects are actually layers (rather than group layers or service layers), then calls the fixLayer function for those layers. (I've posted these snippets in two separate chunks below to make it easier to follow).

In the end, I'm getting this error message:

Traceback (most recent call last):
  File "<module1>", line 67, in <module>
  File "<module1>", line 38, in fixLayer
  File "E:\sw_nt\ArcGIS\Desktop10.3\ArcPy\arcpy\utils.py", line 182, in fn_
    return fn(*args, **kw)
  File "E:\sw_nt\ArcGIS\Desktop10.3\ArcPy\arcpy\_mapping.py", line 681, in replaceDataSource
return convertArcObjectToPythonObject(self._arc_object.replaceDataSource(*gp_fixargs((workspace_path, workspace_type, dataset_name, validate), True)))
ValueError: Layer: Unexpected error

The traceback to Line 67 is where I call the function; I'm calling it on the right hand side of the assignment statement in order to return the shpCount, FCCount and cvgCount variables to the global level. Is this a problem?

Here is the fixLayer function:

def fixLayer(x2):
    shpCount,FCCount,cvgCount = 0,0,0
if (x2.supports("DATASOURCE") and x2.dataSource[0:2] == "L:"): # improve this by subbing in a variable for L: so user can choose what x sources they want to update..
    layerString = x2.workspacePath
    layerName = str(x2.datasetName)
    print '\t',"Layer name is %s and full data source is %s" %(layerName, layerString)
    if x2.dataSource[-4:] == ".shp":    #detect workspace type for any layer source we could find in L:, be it shapefile, feature class or coverage
    #more slick: if extension.lower() == ".shp":
        workspaceType = "SHAPEFILE_WORKSPACE"
        shpCount += 1
    elif '.gdb' in layerString:
        workspaceType = "FILEGDB_WORKSPACE"
        FCCount += 1
    else:
        workspaceType = "COVERAGE_WORKSPACE"
        cvgCount += 1
    print '\t', "%s has workspace type:  %s " %(layerString,workspaceType)
    newLayerString = str(layerString.replace(r"L:",r"W:\FOR\RSI\DKL\Local_Data",1))
    print "Checking arguments for .replaceDataSource:"
    print "Arguments are:\n 1. Workspace path: %s of type %s\n 2. Workspace type: %s of type %s and \n 3. Dataset name: %s of type %s" %(newLayerString,type(newLayerString),workspaceType,type(workspaceType), layerName, type(layerName))
    #Syntax for below:                 .replaceDataSource(workspace_path, workspace_type, dataset_name, {validate})
    lyr.replaceDataSource(newLayerString,workspaceType,layerName)
    #layerFile.replaceDataSource does not work because layerFile is a string; lyr is an object, which is required for the .replaceDataSource method
    lyr.save() #you've made changes to the object, now those changes need to be saved to the file
    print '\t',"The updated source for %s is %s." %(x2.name,lyr.dataSource)
else:
       print '\t', "Layer source does not need update."
return shpCount,FCCount,cvgCount

Here is my "Step 1" code block:

# Step 1: re-map layers in .lyr files in the main path
for layerFile in glob.glob(folder + "/*.lyr"):  #layerFile is a string
    lyrCount += 1
    lyr = arcpy.mapping.Layer(layerFile)  # returns the object from each layer file
    layers = arcpy.mapping.ListLayers(lyr) # returns the list of objects (i.e. the layer name, group layers (if any) and actual layers) referenced by the layer file
    print""
    print "Layer file is %s." %(layerFile)
    objectCount = 0
    grpLayerCount = 0
    for x in layers:
        objectCount +=1
        if x.isGroupLayer:
            grpLayerCount += 1
            print "%d. **GROUP LAYER** Object is %s." %( objectCount,str(x))
        elif x.isServiceLayer == 1:
            srvcCount += 1
            print"%s is a WMS layer" %(x.name)
        else:
            print "%d. Object is %s" %( objectCount,str(x))
            layerCount +=1
            a,b,c = fixLayer(x) #a,b,c correspond to the returned variables in fixLayer:  shpCount,FCCount,cvgCount
    shpCount += a
    FCCount += b
    cvgCount += c

   print""
   print"%s has %d objects including %d group layer(s)." %(layerFile,  len(layers),grpLayerCount)
   print "=========================================================================================="