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 have seen many questions posted that are similar to mine but still havent found the answer so figured I would post my script. I want to change all the data sources found in all mxds in a location to point to one geodatabase. The mxds are currently referencing feature classes, shapefiles and rasters. I am wondering if there is an issue with the shapefiles that have now been moved to the gdb and no longer have the file extension.. even if so why wouldn't the feature classes sources change? Here is what I have, it runs, but there are no changes to the data sources that I can see.

UPDATE: I've now modified it to use lyr.ReplaceDataSource, which works it changing the data source for the first shapefile it encounters in the mxds, but it doesn't change the source for the other feature classes and rasters.

UPDATE 2: Im still struggling to find the answer here. I now am trying to use findandreplaceworkspacepaths on each mxd, and again the script runs, but the data sources don't change. I am printng out the old and new paths in the script and they are printing correctly.. so what is happening?? updated code below:

import arcpy, os
mxd_path = r'C:\GIS\Assimilate_Mxd_Data\Assimilate_Mxd_Data_TESTING\Input Mxd'
new_path = r'C:\GIS\Assimilate_Mxd_Data\Assimilate_Mxd_Data_TESTING\Output Data\test_output.gdb'
mxd_list = []

for dirpath, dirnames, filenames in os.walk(mxd_path):
    for filename in filenames:
        fullPath = os.path.join(dirpath, filename)
        basename, extension = os.path.splitext(filename)
        if extension == ".mxd":
            each_mxd = fullPath
            mxd_list.append(each_mxd)
for m in mxd_list:
    mxd = arcpy.mapping.MapDocument(m)
    for lyr in arcpy.mapping.ListLayers(mxd):
        if lyr.supports("DATASOURCE"):
            old_path = lyr.dataSource
            mxd.findAndReplaceWorkspacePaths(old_path,new_path,validate=True)
            print old_path,new_path
mxd.save()
del mxd
share|improve this question
    
If nothing happens, then add some print messages to debug; after if lyr.supports I'd place an arcpy.AddMessage() statement to see if your script is even getting to that point. –  Mintx Oct 16 '13 at 15:31
    
yes I will do that –  kflaw Oct 16 '13 at 15:45
    
Remember to set validate to True so you'll get some feedback if something is going wrong. lyr.replaceDataSource(new_path,"FILEGDB_WORKSPACE", validate=True) –  Jason Scheirer Oct 16 '13 at 17:19
    
You don't need to save the mxd after each data source is replaced, rather save once the for loop has finished with the layers (shift mxd.save() four spaces back). –  Arabella Oct 17 '13 at 5:58

1 Answer 1

old_path = lyr.dataSource will give you the whole data path, not just the workspace path. Try instead using old_path = os.path.dirname(lyr.dataSource). I'd also recommend setting that third validate argument to true (lyr.findAndReplaceWorkspacePath(old_path, new_path, True)) so you'll at least be given an error if updating fails. I'd also only save the MXD once.

import os

import arcpy

mxd_path = r'C:\GIS\Assimilate_Mxd_Data\Assimilate_Mxd_Data_TESTING\Input Mxd'
new_path = r'C:\GIS\Assimilate_Mxd_Data\Assimilate_Mxd_Data_TESTING\Output Data\test_output.gdb'

for dirpath, dirnames, filenames in os.walk(mxd_path):
    for filename in filenames:
        fullPath = os.path.join(dirpath, filename)
        basename, extension = os.path.splitext(filename)
        if extension.lower() == ".mxd":
            has_data_source = False
            mxd = arcpy.mapping.MapDocument(fullPath)
            for lyr in arcpy.mapping.ListLayers(mxd):
                if lyr.supports("DATASOURCE"):
                    old_path = os.path.dirname(lyr.dataSource)
                    lyr.findAndReplaceWorkspacePath(old_path, new_path, True)
                    has_data_source = True
            if has_data_source:
                mxd.save()
share|improve this answer
    
I think i actually need to be using lyr.replaceDataSource, since I want to change workspace types. I've gotten it to work for the first shapefile it encounters, but then not for anything else. I'll repost my code. –  kflaw Oct 16 '13 at 15:43

Your Answer

 
discard

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

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