replaceDataSource Not Working

2408
9
04-02-2012 12:40 PM
JohnStephens1
New Contributor
So I have a map with a bunch of ASC files that have been updated and I need to relink them all.  I am trying to use replaceDataSource, but it just links all the files to the first ASC file in the folder.

import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
for lyr in arcpy.mapping.ListLayers(mxd, "SSPA_RIFS_Alt*"):
    if lyr.supports("DATASOURCE"):
        lyr.replaceDataSource(r"C:\Folder", "NONE", file_name)
del mxd


Ignore "file_name" but it's a variable I've set to collect the right name for each ASC based on the layer name in the map.  (it works, I've checked it with print messages).

I've also tried using "RASTER_WORKSPACE" instead of "NONE" for the workspace type, but I get the same results.

Any ideas?
0 Kudos
9 Replies
MathewCoyle
Frequent Contributor
You could try using "TEXT_WORKSPACE" since .asc files are text. Also, did you try using an mxd.save() or mxd.saveACopy(...)?
0 Kudos
JohnStephens1
New Contributor
You could try using "TEXT_WORKSPACE" since .asc files are text. Also, did you try using an mxd.save() or mxd.saveACopy(...)?


When I use "TEXT_WORKSPACE" it throws a ValueError exception.  And saving the mxd doesn't have any affect.
0 Kudos
MathewCoyle
Frequent Contributor
Posting your full code may help, I suspect a problem with your file_name variable, as well as the specific errors you are receiving. The code you posted works fine for me, modified thusly.
import arcpy
changedir = r"D:\GIS\ascii"
mxd = arcpy.mapping.MapDocument("CURRENT")
for lyr in arcpy.mapping.ListLayers(mxd):
    if lyr.supports("DATASOURCE"):
        file_name = lyr.name
        lyr.replaceDataSource(changedir, "NONE", file_name)
0 Kudos
JohnStephens1
New Contributor
mzcoyle;186689 wrote:
Posting your full code may help, I suspect a problem with your file_name variable, as well as the specific errors you are receiving. The code you posted works fine for me, modified thusly.


It's a bit clunky.  Some of the information is sensitive, so here is the best I can do:

(I just made things a bit more generic)

import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
for lyr in arcpy.mapping.ListLayers(mxd, "Plume_Layer*"):
    if lyr.supports("DATASOURCE"):
        lyr_name = lyr.name
        name_parts = lyr_name.split("_")
        var1 = name_parts[2]
        var2 = name_parts[5]
        years = int(name_parts[7])
        var3 = name_parts[9].lstrip("L")
        if years <= 5:
            months = "0" + str(years*12)
        elif years == 48:
            months = "313"
        elif years == 76:
            months = "313"
        else:
            months = str(years*12)

        if years <> 48:
            days = years * 365
            days = str(days) + ".00"
        else:
            days = "17699.84"
            
        file_name = var1 + "_" + "BC" + "_" + "SP0" + months + "_" + "L000" + var3 + "_T" + days + ".ASC"
        lyr.replaceDataSource(r"C:\Folder", "NONE", file_name)
del mxd


So a sample layer in the map is just a bunch of variables separated by underscores, like:
"XXX_XXX_[var1]_XXX_XXX_[var2]_XXX_[years]_XXX_[var3]"

And a file name in the folder is like this:
"[var1]_BC_SP0[months]_L000[var3]_T[days].ASC"

When you tried the code you had, did you run it on multiple files?  Mine runs, it just links everything to the same file (which is incorrect obviously).
0 Kudos
MathewCoyle
Frequent Contributor
Yes mine ran on multiple .asc files.

Did the names of your files change when you moved them? You could do something like this

filename = os.path.basename(lyr.dataSource)
0 Kudos
JohnStephens1
New Contributor
Yes mine ran on multiple .asc files.

Did the names of your files change when you moved them? You could do something like this

filename = os.path.basename(lyr.dataSource)


It's kind of difficult to explain.  They didn't change, but more layers were added.  So it's necessary to code in the "new" filenames.
0 Kudos
MathewCoyle
Frequent Contributor
Not sure what else to suggest. It seems a very odd workflow to have source filenames that depend on the layer name as a process. I'm not sure why you are assigning the same month value for different year values,
        elif years == 48:
            months = "313"
        elif years == 76:
            months = "313"

but without seeing actual examples of filenames/paths etc I can't help much more.
0 Kudos
JohnStephens1
New Contributor
Not sure what else to suggest. It seems a very odd workflow to have source filenames that depend on the layer name as a process. I'm not sure why you are assigning the same month value for different year values,
        elif years == 48:
            months = "313"
        elif years == 76:
            months = "313"

but without seeing actual examples of filenames/paths etc I can't help much more.


It's a run for a model that simulates predicted outputs.  The model has 4 layers.  There are also 4 versions of the models with different parameters.  So, you have many file names that use the same year.  Why the modelers have the month count screwed up for those different years, I don't know.  That's just how it works.

We continuously run the model when the client wants to tweak new things.  That used to be an easy fix, because I would just change the folder the files are pointed at.  However, for recent runs they want exports for all the layers (it used to be just 1).  So, without having to reset the symbology on hundreds of layers, I just copied the layers in the TOC and changed their names.  Then I was hoping to get this script to link the files based on the layer name to the file.

It might seem backwards, but the alternative solutions are much, much more time consuming.

Thanks for trying.
0 Kudos
JohnStephens1
New Contributor
Well, I found the problem.  Python apparently does not like to see ".00." in a path or filename.  I have no idea, but that's where the code was hanging up.

A simple batch script to change my filenames and get rid of ".00." worked.
0 Kudos