Select to view content in your preferred language

ReplaceDataSource not working in script

4731
10
07-20-2010 04:10 AM
ChristianHalsted
Occasional Contributor
I am trying to write a script tool that will loop through all the disconnected layers in a map document and repoint them using the Layer.replaceDataSource function.  When I run the following 3 lines of code:

mxd = arcpy.mapping.MapDocument("CURRENT")
lyr = arcpy.mapping.ListBrokenDataSources(mxd)[0]
lyr.replaceDataSource(r"Database Connections\GISUSER on dep-eia1dbsop01.sde","SDE_WORKSPACE",r"Sample_Location",True)

from the Python Window within ArcGIS Desktop it works fine.  But when I put them in a .py file and try to run the script from ArcToolbox it seems to reconnect the file but then removes it from the map document.
0 Kudos
10 Replies
GünterDörffel
Frequent Contributor
Hi Christian,

as far as I understood the "CURRENT" option is basically meant to be used from within the python-Window.
Try to parse the full mxd-Path as an argument into your script and make the document line get that

mxd = arcpy.mapping.MapDocument(r"C:\temp\xxtest.mxd")


Havent tried but its worth a try!
Regards
Guenter
0 Kudos
RandyKreuziger
Frequent Contributor
Question about saving the mxd.  Is there a way to determine the version of an mxd so when saving out the mxd it can be saved to the same version?  Our users are running mostly 9.3 but some have 9.2 mxds that break at 9.3 so they want their mxds fixed and saved to that version.
0 Kudos
GünterDörffel
Frequent Contributor
Hi Randy,

you should have opened a seperate thread for that ...

I know of no python way to get this. ArcObjects I think to remember there is one ...

In python you can use the

saveACopy (file_name, {version})


method to save to a previous version - but unless you havent used any of the potential document properties to store a helper string in (like description, summary, tags ...) you will have to "guess" which version this is. Maybe the read-only property

dateSaved


could help to evaluate which version this is ...


Regards
Guenter
0 Kudos
ChristianHalsted
Occasional Contributor
Hi Christian,

as far as I understood the "CURRENT" option is basically meant to be used from within the python-Window.
Try to parse the full mxd-Path as an argument into your script and make the document line get that

mxd = arcpy.mapping.MapDocument(r"C:\temp\xxtest.mxd")


Havent tried but its worth a try!
Regards
Guenter


Thank you for this suggestion.  However, I've used "CURRENT" successfully in a number of other script tools.  Plus, I get the same result when I use the full mxd path.  I think this has to be a bug in the software.
0 Kudos
CosminTana
Emerging Contributor
I experience exactly the same problem and I have SP 1 installed...

If I use :

mxd=arcpy.mapping.MapDocument('Current')
df= arcpy.mapping.ListDataFrames(..)
old_lyr=arcpy.mapping.ListLayers(..)
old_lyr.replaceDataSource(..)

from withon the Pythonwin in Arcmap everything is fine.
If I do the exactly the same in a script, it seems the layer changes(for a sec), but when the script finishes the layer disappears.


The best way in my opinion, is to remove the the layer from the dataframe, then to replace the datasource and finally to add the layer again into the dataframe.

mxd=arcpy.mapping.MapDocument('Current')
df= arcpy.mapping.ListDataFrames(..)
old_lyr=arcpy.mapping.ListLayers(..)
arcpy.mapping.RemoveLayer(..)
old_lyr.replaceDataSource(..)
arcpy.mapping.AddLayer(..) / InsertLayer(..)

This is the shortest workaround I could find...
Hope it helps, even though your post is quite old...
0 Kudos
RuthEmerick
Emerging Contributor
I've had that problem recently. It occurs for me when I have multiple data frames that contain some of the same layers. I've fixed this by calling the layers inside the data frames like this:

import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
newSdePath = r"Database Connections\My Connection.sde"

for df in arcpy.mapping.ListDataFrames(mxd):
        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
                lyr.replaceDataSource(newSdePath, "SDE_WORKSPACE", lyr.datasetName, False)

arcpy.RefreshTOC()
arcpy.RefreshActiveView()
mxd.save()
del mxd


It's also helpful to check that you can use the dataSource and datasetName functions on your layers before attempting replaceDataSource:

import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
newSdePath = r"Database Connections\My Connection.sde"

for df in arcpy.mapping.ListDataFrames(mxd):
        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
                if (lyr.supports("DATASOURCE") and lyr.supports("datasetName")):
                        lyr.replaceDataSource(newSdePath, "SDE_WORKSPACE", lyr.datasetName, False)

arcpy.RefreshTOC()
arcpy.RefreshActiveView()
mxd.save()
del mxd


I also had problems with the SDE paths, notably that my features were inside feature classes, and that I wanted to make sure that I was only replacing data sources that were in my old SDE (e.g. not in a file gdb on my local drive), so I came up with this:

import arcpy, os
mxd = arcpy.mapping.MapDocument("CURRENT")
newSdePath = r"Database Connections\My Connection.sde"
oldSdePath = r"Database Connections\My Old Connection.sde"

for df in arcpy.mapping.ListDataFrames(mxd):
        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
                if (lyr.supports("DATASOURCE") and lyr.supports("datasetName")):
                        tempDataSetPath, tempDataSet = os.path.split(lyr.dataSource)
                        tempDataSetPath, tempDataSetClass = os.path.split(tempDataSetPath)
                        if lyr.dataSource == os.path.join(oldSdePath, tempDataSetClass, lyr.datasetName):
                                lyr.replaceDataSource(newSdePath, "SDE_WORKSPACE", lyr.datasetName, False)

arcpy.RefreshTOC()
arcpy.RefreshActiveView()
mxd.save()
del mxd


I hope this is useful.
0 Kudos
CosminTana
Emerging Contributor
Thanks for providing your code and sharing your experience.
I haven't worked with SDE Connections yet, but if I ever have to, I now know where to look first for it 🙂

I think I was wrong, since SP1 is out, replaceDataSoruces works without removing and inserting the layer again. So it was only a bug before SP1.

Anyway, this thread due to your code now, could help a lot of people. Thanks.
0 Kudos
RuthEmerick
Emerging Contributor
In case anyone else tries to use the replaceDatasource function, there's a fairly significant problem if you try to change very many sde data sources at a time. See this post.
0 Kudos
BrettElliot
Deactivated User
I'm having the same issue when running my python script. 

It connects the layers fine, then immediately removes them.

Is this a known bug?
0 Kudos