Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I appear to be having difficulty with using 'replaceDataSource'. ESRI has atrocious documentation on updating and fixing data sources, and almost everything I have read on the subject is almost what I am looking for, but not quite.

What I am looking for is a way to repair multiple map documents without having to specify the name of each layer that has a broken data source.

The code I have written so far should loop through the map documents in a directory, find which layers have a broken data source and determine if it is a shapefile, personal geodatabase feature class, file geodatabase feature class or a raster.

The code determines the name of the feature class or shapefile, and uses the 'replaceDataSource' to fix the broken data source.

When the script is run in the Python window in ArcMap, it points to their being an error on the lines that contain 'lyr.replaceDataSource' bit of code along with Info: Layer: Unexpected error

When the script is run in PyScripter, the first datasource is a shapefile and it gives an error message but keeps running: Info: Layer: Unexpected error and nothing else.

However, as soon as it runs into a feature class in a personal geodatabase, python crashes and gives this message: exceptions.EOFError: [Errno 10054] An existing connection was forcibly closed by the remote host

I suspect the primary reason the script is not working may be the manner is which the broken data sources are determined, but really have no idea.

Currently using ArcGIS 10.2, python version 2.7.3 and PyScripter.

Here is an edited, pared down version of the code, with the full code following:

import arcpy, os, sys, traceback

workspace = arcpy.env.workspace = r'c:\users\athom\Documents\GIS\GIS_computer_06_20_2013\GIS_LOCAL_MASTER\MAPS\Map_Projects\TEST'
mxdList = arcpy.ListFiles("*.mxd")
for Map in mxdList:
    filePath = os.path.join(workspace, Map)
    mxd = arcpy.mapping.MapDocument(filePath)
    brkLayerList = arcpy.mapping.ListBrokenDataSources(mxd)
    for lyr in brkLayerList:
        if lyr.supports("DATASOURCE") and lyr.supports("WORKSPACEPATH"):
            brokenDataSource = lyr.dataSource
            if brokenDataSource.startswith('n'):
                newDataSource = brokenDataSource.replace(r'n:', r'c:\users\athom\Documents\GIS\GIS_computer_06_20_2013\GIS_LOCAL_MASTER')
                layerName = lyr.datasetName
                ChangedDataSet = newDataSource.replace(layerName, '')
                try:
                    if "shp" in newDataSource:
                        ChangedDataSet =ChangedDataSet.replace(' ','')[:-4]
                        layerName = layerName+'.shp'
                        lyr.replaceDataSource(ChangedDataSet, "SHAPEFILE_WORKSPACE", layerName, True)
                        lyr.save()
                    elif "mdb" in newDataSource:
                        lyr.replaceDataSource(ChangedDataSet, "ACCESS_WORKSPACE", layerName, True)
                        lyr.save()
                    elif "gdb" in newDataSource:
                        lyr.replaceDataSource(ChangedDataSet, "FILEGDB_WORKSPACE", layerName, True)
                        lyr.save()
                    else:
                        lyr.replaceDataSource(ChangedDataSet, "RASTER_WORKSPACE", layerName, True)
                        lyr.save()
                except Exception as e:
                    print arcpy.AddError(e)
                    print "N FAILED"
            else:
                print 'Data Source Lost'

    mxd.save()
    del mxd

Full code with error checking.

import arcpy, os, sys, traceback

workspace = arcpy.env.workspace = r'c:\users\athom\Documents\GIS\GIS_computer_06_20_2013\GIS_LOCAL_MASTER\MAPS\Map_Projects\TEST'
mxdList = arcpy.ListFiles("*.mxd")
for Map in mxdList:
    filePath = os.path.join(workspace, Map)
    mxd = arcpy.mapping.MapDocument(filePath)
    brkLayerList = arcpy.mapping.ListBrokenDataSources(mxd)
    for lyr in brkLayerList:
        if lyr.supports("DATASOURCE") and lyr.supports("WORKSPACEPATH"):
            brokenDataSource = lyr.dataSource
            print brokenDataSource
            if brokenDataSource.startswith('N'):
                newDataSource = brokenDataSource.replace(r'N:', r'c:\users\athom\Documents\GIS\GIS_computer_06_20_2013\GIS_LOCAL_MASTER')
                layerName = lyr.datasetName
                ChangedDataSet = newDataSource.replace(layerName, '')
                print newDataSource
                print ChangedDataSet
                print layerName
                try:
                    if "shp" in newDataSource:
                        try:
                            ChangedDataSet =ChangedDataSet.replace(' ','')[:-4]
                            print ChangedDataSet
                            lyr.replaceDataSource(ChangedDataSet, "SHAPEFILE_WORKSPACE", layerName, True)
                            lyr.save()
                        except:
                            tb = sys.exc_info()[2]
                            tbinfo = traceback.format_tb(tb)[0]
                            pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
                            msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
                            arcpy.AddError(pymsg)
                            arcpy.AddError(msgs)
                            print pymsg + "\n"
                            print msgs

                    elif "mdb" in newDataSource:
                        try:
                            lyr.replaceDataSource(ChangedDataSet, "ACCESS_WORKSPACE", layerName, True)
                        except:
                            tb = sys.exc_info()[2]
                            tbinfo = traceback.format_tb(tb)[0]
                            pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
                            msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
                            arcpy.AddError(pymsg)
                            arcpy.AddError(msgs)
                            print pymsg + "\n"
                            print msgs

                    elif "gdb" in newDataSource:
                        try:
                            lyr.replaceDataSource(ChangedDataSet, "FILEGDB_WORKSPACE", layerName, True)
                        except:
                            tb = sys.exc_info()[2]
                            tbinfo = traceback.format_tb(tb)[0]
                            pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
                            msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
                            arcpy.AddError(pymsg)
                            arcpy.AddError(msgs)
                            print pymsg + "\n"
                            print msgs
                    else:
                        try:
                            lyr.replaceDataSource(ChangedDataSet, "RASTER_WORKSPACE", layerName, True)
                        except:
                            tb = sys.exc_info()[2]
                            tbinfo = traceback.format_tb(tb)[0]
                            pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
                            msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
                            arcpy.AddError(pymsg)
                            arcpy.AddError(msgs)
                            print pymsg + "\n"
                            print msgs
                except Exception as e:
                    print arcpy.AddError(e)
                    print "N FAILED"

            elif brokenDataSource.startswith ('n'):
                newDataSource = brokenDataSource.replace(r'n:', r'c:\users\athom\Documents\GIS\GIS_computer_06_20_2013\GIS_LOCAL_MASTER')
                layerName = lyr.datasetName
                ChangedDataSet = newDataSource.replace(layerName, '')
                print newDataSource
                print ChangedDataSet
                print layerName
                try:
                    if "shp" in newDataSource:
                        try:
                            ChangedDataSet =ChangedDataSet.replace(' ','')[:-4]
                            print ChangedDataSet
                            lyr.replaceDataSource(ChangedDataSet, "SHAPEFILE_WORKSPACE", layerName, True)
                        except:
                            tb = sys.exc_info()[2]
                            tbinfo = traceback.format_tb(tb)[0]
                            pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
                            msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
                            arcpy.AddError(pymsg)
                            arcpy.AddError(msgs)
                            print pymsg + "\n"
                            print msgs
                    elif "mdb" in newDataSource:
                        try:
                            lyr.replaceDataSource(ChangedDataSet, "ACCESS_WORKSPACE", layerName, True)
                        except:
                            tb = sys.exc_info()[2]
                            tbinfo = traceback.format_tb(tb)[0]
                            pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
                            msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
                            arcpy.AddError(pymsg)
                            arcpy.AddError(msgs)
                            print pymsg + "\n"
                            print msgs

                    elif "gdb" in newDataSource:
                        try:
                            lyr.replaceDataSource(ChangedDataSet, "FILEGDB_WORKSPACE", layerName, True)
                        except:
                            tb = sys.exc_info()[2]
                            tbinfo = traceback.format_tb(tb)[0]
                            pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
                            msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
                            arcpy.AddError(pymsg)
                            arcpy.AddError(msgs)
                            print pymsg + "\n"
                            print msgs
                    else:
                        try:
                            lyr.replaceDataSource(ChangedDataSet, "RASTER_WORKSPACE", layerName, True)
                        except:
                            tb = sys.exc_info()[2]
                            tbinfo = traceback.format_tb(tb)[0]
                            pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
                            msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
                            arcpy.AddError(pymsg)
                            arcpy.AddError(msgs)
                            print pymsg + "\n"
                            print msgs
                except arcpy.ExecuteError:
                    arcpy.AddError(GetMessages(2))
                    print "n FAILED"

            else:
                print 'Data Source Lost'

    mxd.save()
    del mxd
share|improve this question
    
Do you get the same error when you try to run this from IDLE and/or the Python window of ArcMap? Please use the edit button under your Question to revise it with your thoughts on whether it is a PyScripter specific or Python IDE generic issue. –  PolyGeo Feb 4 at 1:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.