3

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
3
  • 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
    Commented Feb 4, 2014 at 1:16
  • 1
    Voting to close as too localized. Q is old with little to no follow up, and unlikely to help future visitors in its present form. (that said, I will toss one possible life-raft: this sounds similar to my problems with validate when changing layer file paths gis.stackexchange.com/questions/6884/…) Commented Jan 7, 2015 at 17:35
  • @mattwilkie it is almost identical to your question with the exception that the data I am using is stored in a variety of formats. The script would conk out as soon as it reached a layer with a .mdb datasource with an 'Unexpected Error' message in the python window in ArcMap, and now returns 'Access Violation at address .......' in PyScripter. As I doubt anyone will come up with a solution, it is probably a good question to close.
    – Adam Thom
    Commented Jan 7, 2015 at 20:00

0