I have one script (and one alternative) that I want to use to replace a broken data source. Neither is working outside of the ArcMap Python Window. Has it something to do with the MapDocument object?

  • Tested with a few different IDEs; including PyScripter, Pythonwin, PyCharm and IDLE.

  • In both instances the scripts run without error and print the correct print statements, but nothing is changed in the map document.

  • Only tested using Python 2.7.13 because when working with the arcpy module and ArcMap, Python 3.x is not supported. It's supported in ArcPro.

  • No difference with mxd.saveACopy() instead of mxd.save()

Script using replaceDataSource()

mxd = arcpy.mapping.MapDocument(r'\\gisfile\GISmaps\AtlasMaps\ATLAS_MAPS_18\Test 
Folder\Beecher_Unit_200U_B.mxd')
for lyr in arcpy.mapping.ListLayers(mxd):
    if str(lyr.name) == "Test":
        lyr.replaceDataSource(r"\\gisfile\GISstaff\Jared\Hydro.gdb", "FILEGDB_WORKSPACE", "Hydro_WillCounty_Waterways")
        print(lyr.dataSource)
mxd.save()
del mxd

and using findAndReplaceWorkspacePaths()

mxd = arcpy.mapping.MapDocument(r'\\gisfile\GISmaps\AtlasMaps\ATLAS_MAPS_18\Test 
Folder\Joliet_Elem_86_B.mxd')
mxd.findAndReplaceWorkspacePaths(r"\\gisfile\GISmaps\GISstaff\Jared\WillCoGIS_DataSHP.gdb", r"\\gisfile\GISstaff\Jared\Hydro.gdb")
mxd.save()
del mxd

On the other hand, these scripts work fine in the ArcMap Python window. For example,

import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
for lyr in arcpy.mapping.ListLayers(mxd):
if str(lyr.name) == "Test":
   lyr.replaceDataSource(r"\\gisfile\GISstaff\Jared\Hydro.gdb", 
   "FILEGDB_WORKSPACE", "Hydro_WillCounty_Waterways")
   print lyr.dataSource
mxd.save()
del mxd

I've had a look at similar posts, but I couldn't find one helpful enough:

Same python code works in arcgis python window, but fails in pyScripter

Code Works in Python Window but not Script

Why does FeatureClassToFeatureClass work in ArcMap but not in Python script?

  • Is your script running as a user with write access to the location where the map documents are? Does it have the ability to read the location where the other file gdb is located? Is your IDE using the same python installation as arcpy? What error message are you getting from your script? – Fezter Nov 9 at 3:16
  • Yes, I have access to the workspace folder. It's on our server. Yes, as I said, both scripts run with no error and where there are print statements they work as they should. There is no error message anywhere. – Pfalbaum Nov 9 at 14:29

After creating an alternative script that unorthodoxically replaces the broken layer, I was able to find the problem in my original stand-alone script. It seems something is corrupt in the path to, or the FGDB itself. So, I replaced the parameters in the replaceDataSource() function to call a feature class in our SDE instead. And it worked.

lyr.replaceDataSource(r"Database Connections\example.sde", 
"SDE_WORKSPACE", "feature class example")

For curiosity's sake, here's that unorthodox script. It's a long workaround if you don't have many options as to where your data is stored, or you don't want to use the options from this page:

http://desktop.arcgis.com/en/arcmap/10.3/analyze/arcpy-mapping/updatingandfixingdatasources.htm

This script will:

Remove broken layer (has to be specified by exact map layer name)--> Adds a new layer--> Updates that layer's symbology by importing a .lyr file that's saved with the symbology settings you want--> Moves this layer above another layer (puts it where you want it in the TOC)

import arcpy

#variables
mxd = arcpy.mapping.MapDocument(r'path\to\.mxd')
df = arcpy.mapping.ListDataFrames(mxd, "name of dataframe")[0]
feature = arcpy.mapping.Layer(r"path\to\feature you want on map")

for lyr in arcpy.mapping.ListLayers(mxd, "featureclass", df): #the layer you're 
replacing
    arcpy.mapping.RemoveLayer(df, lyr) #because this layer is broke, it will be removed
    arcpy.mapping.AddLayer(df, feature, "AUTO_ARRANGE") #then 'feature' has to be re-added, but will be the wrong color
    #the 'feature' will be updated by the .lyr file you created
    updateLayer = arcpy.mapping.ListLayers(mxd, "name of feature", df)[0] 
    print("MXD: {} updated").format(mxd)#print statement to make sure it's working sofar
    sourceLayer = arcpy.mapping.Layer(r"path\to\your\.lyr")
    #update layer using the .lyr file's symbology
    arcpy.mapping.UpdateLayer(df, updateLayer, sourceLayer, True)

#move layer to where you want in the TOC
for lyr2 in arcpy.mapping.ListLayers(mxd, "", df):
    if lyr2.name == "feature name":
        moveLayer = lyr2
if lyr2.name == "some other feature in the TOC":
    refLayer = lyr2
arcpy.mapping.MoveLayer(df, refLayer, moveLayer, "BEFORE")
mxd.save()
del mxd

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.