Update\change features data source.

3386
19
01-28-2014 01:10 PM
TonyAlmeida
Occasional Contributor II
I have some layers that i need to change the data source for.

The current script i have gives me the following error. I don't know why.
if anyone would be kind to help me out please?
thanks.


import arcpy
from arcpy import env
from arcpy import mapping

workspace = arcpy.env.workspace =  "C:/GIS/MAPBOOK/Proposed Zoning Book"

arcpy.env.overwriteOutput = True

mxdList = arcpy.ListFiles("*.mxd")

for mxd in mxdList:
    mxd = workspace + "//" + mxd
    for lyr in arcpy.mapping.ListLayers(mxd): 
        if lyr.name == "PROPOSED ZONING":
                lyr.replaceDataSource("C:/Users/t***a/AppData/Roaming/ESRI/Desktop10.1/ArcCatalog/DSD15_SQLEXPRESS.gds/DSD/DSD.DBO.MUNICIPALITY", "SHAPEFILE_WORKSPACE", "DSD.DBO.FUTURE_LAND_USE_ZONING")
    for lyr in arcpy.mapping.ListLayers(mxd): 
        if lyr.name == "CITY LIMITS":
                lyr.replaceDataSource("C:/Users/t***a/AppData/Roaming/ESRI/Desktop10.1/ArcCatalog/DSD15_SQLEXPRESS.gds/TonyOneWay/TonyOneWay.DBO.Canyon_Features", "SHAPEFILE_WORKSPACE", "TonyOneWay.DBO.City_Limits")            
    print "Successfully updated data sources"
    mxd.save()


Error
Traceback (most recent call last):
  File "C:\GIS\Python Scripts\Change Data Source MXD 2.py", line 13, in <module>
    for lyr in arcpy.mapping.ListLayers(mxd):
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\utils.py", line 181, in fn_
    return fn(*args, **kw)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\mapping.py", line 1500, in ListLayers
    result = mixins.MapDocumentMixin(map_document_or_layer).listLayers(wildcard, data_frame)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 823, in listLayers
    layers = self.layers
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 683, in layers
    for frame in reversed(self.dataFrames):
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 695, in dataFrames
    return map(convertArcObjectToPythonObject, self.pageLayout.dataFrames)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 679, in pageLayout
    return convertArcObjectToPythonObject(self._mxd._arc_object.pageLayout)
AttributeError: 'unicode' object has no attribute '_arc_object'
Tags (2)
0 Kudos
19 Replies
JohnDye
Occasional Contributor III
Within your Layer Loops, you're interrogating the Layer.name property.

for lyr in arcpy.mapping.ListLayers(mxd):
        if lyr.name == "PROPOSED ZONING":
                lyr.replaceDataSource("C:/Users/t***a/AppData/Roaming/ESRI/Desktop10.1/ArcCatalog/DSD15_SQLEXPRESS.gds/DSD/DSD.DBO.MUNICIPALITY", "SHAPEFILE_WORKSPACE", "DSD.DBO.FUTURE_LAND_USE_ZONING")
    for lyr in arcpy.mapping.ListLayers(mxd):
        if lyr.name == "CITY LIMITS":
                lyr.replaceDataSource("C:/Users/t***a/AppData/Roaming/ESRI/Desktop10.1/ArcCatalog/DSD15_SQLEXPRESS.gds/TonyOneWay/TonyOneWay.DBO.Canyon_Features", "SHAPEFILE_WORKSPACE", "TonyOneWay.DBO.City_Limits")
    print "Successfully updated data sources"


Problem is, your ListLayers function did not return Layer Objects so you can't interrogate the Layer.name property.
Check out the third line of the Discussion section on the ListLayers Help Document. In order for the ListLayers function to return a Layer Object, you must use an index value on the List like this:

for lyr in arcpy.mapping.ListLayers(mxd)[0]:
        if lyr.name == "PROPOSED ZONING":
                lyr.replaceDataSource("C:/Users/t***a/AppData/Roaming/ESRI/Desktop10.1/ArcCatalog/DSD15_SQLEXPRESS.gds/DSD/DSD.DBO.MUNICIPALITY", "SHAPEFILE_WORKSPACE", "DSD.DBO.FUTURE_LAND_USE_ZONING")
    for lyr in arcpy.mapping.ListLayers(mxd)[0]:
        if lyr.name == "CITY LIMITS":
                lyr.replaceDataSource("C:/Users/t***a/AppData/Roaming/ESRI/Desktop10.1/ArcCatalog/DSD15_SQLEXPRESS.gds/TonyOneWay/TonyOneWay.DBO.Canyon_Features", "SHAPEFILE_WORKSPACE", "TonyOneWay.DBO.City_Limits")
    print "Successfully updated data sources"


Crazy, I didn't know that myself until I investigated your issue. I've just always done it out of habbit.
0 Kudos
TonyAlmeida
Occasional Contributor II
I am still getting the same error with the code.


import arcpy
from arcpy import env
from arcpy import mapping

workspace = arcpy.env.workspace =  "C:/GIS/MAPBOOK/Proposed Zoning Book"

arcpy.env.overwriteOutput = True

mxdList = arcpy.ListFiles("*.mxd")

for mxd in mxdList:
    mxd = workspace + "//" + mxd
    for lyr in arcpy.mapping.ListLayers(mxd[0]:
        if lyr.supports("DATASOURCE"):
            if lyr.name == "PROPOSED ZONING":
                lyr.replaceDataSource("C:/Users/t**a/AppData/Roaming/ESRI/Desktop10.1/ArcCatalog/DSD15_SQLEXPRESS.gds/DSD/DSD.DBO.MUNICIPALITY", "SHAPEFILE_WORKSPACE", "DSD.DBO.FUTURE_LAND_USE_ZONING")
    for lyr in arcpy.mapping.ListLayers(mxd)[0]:
        if lyr.supports("DATASOURCE"):
            if lyr.name == "CITY LIMITS":
                lyr.replaceDataSource("C:/Users/t**a/AppData/Roaming/ESRI/Desktop10.1/ArcCatalog/DSD15_SQLEXPRESS.gds/TonyOneWay/TonyOneWay.DBO.Canyon_Features", "SHAPEFILE_WORKSPACE", "TonyOneWay.DBO.City_Limits")            
    print "Successfully updated data sources"
    mxd.save()


0 Kudos
JohnDye
Occasional Contributor III
Looks like you missed the parenthesis to close out the ListLayers argument.
for lyr in arcpy.mapping.ListLayers(mxd[0]:


Use this instead:
for lyr in arcpy.mapping.ListLayers(mxd)[0]:
0 Kudos
TonyAlmeida
Occasional Contributor II
I saw that i missed the parentheses but after putting in the right syntax it still gives me the same error..?

for lyr in arcpy.mapping.ListLayers(mxd)[0]:
0 Kudos
MichaelVolz
Esteemed Contributor
Can you see if the mxd variable is being properly populated from the list you generate?  Maybe print out the variable in your code.

mxd = workspace + "//" + mxd
0 Kudos
JamesCrandall
MVP Frequent Contributor
Why are you resetting mxd once you start to loop over the list of these mxd's?

mxdList = arcpy.ListFiles("*.mxd")
for mxd in mxdList: #<-- you already have the mxd set here
    mxd = workspace + "//" + mxd #<-- now you are changing it right after you start the loop?  why?
    for lyr in arcpy.mapping.ListLayers(mxd[0]): #<--mxd is likely incorrect now


Instead, remove the mxd setting after the loop

mxdList = arcpy.ListFiles("*.mxd")
for mxd in mxdList: #<-- you already have the mxd set here, just keep it like that
    for lyr in arcpy.mapping.ListLayers(mxd[0]): #<--mxd should now be fine
       .
       .
       .

0 Kudos
TonyAlmeida
Occasional Contributor II
I set to print out variable i got the following.
C:/GIS/MAPBOOK/Proposed Zoning Book//Proposed_ZoningMapBook_Page_1.mxd is being processed

Traceback (most recent call last):
  File "C:\GIS\Python Scripts\Change Data Source MXD 2.py", line 14, in <module>
    for lyr in arcpy.mapping.ListLayers(mxd)[0]:
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\utils.py", line 181, in fn_
    return fn(*args, **kw)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\mapping.py", line 1500, in ListLayers
    result = mixins.MapDocumentMixin(map_document_or_layer).listLayers(wildcard, data_frame)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 823, in listLayers
    layers = self.layers
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 683, in layers
    for frame in reversed(self.dataFrames):
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 695, in dataFrames
    return map(convertArcObjectToPythonObject, self.pageLayout.dataFrames)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 679, in pageLayout
    return convertArcObjectToPythonObject(self._mxd._arc_object.pageLayout)
AttributeError: 'unicode' object has no attribute '_arc_object'


Removing the mxd = workspace + "//" + mxd gives me.

Traceback (most recent call last):
  File "C:\GIS\Python Scripts\Change Data Source MXD 2.py", line 12, in <module>
    for lyr in arcpy.mapping.ListLayers(mxd)[0]:
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\utils.py", line 181, in fn_
    return fn(*args, **kw)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\mapping.py", line 1500, in ListLayers
    result = mixins.MapDocumentMixin(map_document_or_layer).listLayers(wildcard, data_frame)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 823, in listLayers
    layers = self.layers
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 683, in layers
    for frame in reversed(self.dataFrames):
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 695, in dataFrames
    return map(convertArcObjectToPythonObject, self.pageLayout.dataFrames)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 679, in pageLayout
    return convertArcObjectToPythonObject(self._mxd._arc_object.pageLayout)
AttributeError: 'unicode' object has no attribute '_arc_object'
0 Kudos
MichaelVolz
Esteemed Contributor
C:/GIS/MAPBOOK/Proposed Zoning Book//Proposed_ZoningMapBook_Page_1.mxd is being processed

Not sure if this is the cause of your problem but you have 1 set of // in your path but the other parts of the path are separated by /.
0 Kudos
TonyAlmeida
Occasional Contributor II
Why would it be adding  // in the print of C:\GIS\MAPBOOK\Proposed Zoning Book//Proposed_ZoningMapBook_Page_1.mxd is being processed???

This is giving me a headache....


I tried the follwoing and it gives me the same error.

import arcpy
from arcpy import env
from arcpy import mapping

workspace = arcpy.env.workspace =  "C:\GIS\MAPBOOK\Proposed Zoning Book"

arcpy.env.overwriteOutput = True

mxdList = arcpy.ListFiles("*.mxd")

for mxd in mxdList:
    mxd = workspace + "//" + mxd
    print mxd + " is being processed"
    mxd = arcpy.mapping.MapDocument(mxd)
    mxd.findAndReplaceWorkspacePaths(r"C:\Documents and Settings\talmeida\Application Data\ESRI\ArcCatalog\DSDccarcsde.sde",r"C:\Users\talmeida\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog\DBO.DSD.VECTOR.sde")
    for lyr in arcpy.mapping.ListLayers(mxd)[0]:
        if lyr.supports("DATASOURCE"):
            if lyr.name == "PROPOSED ZONING":
                lyr.replaceDataSource(r"C:\Users\talmeida\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog\DSD15_SQLEXPRESS.gds\DSD\DSD.DBO.MUNICIPALITY", "FILEGDB_WORKSPACE", "DSD.DBO.FUTURE_LAND_USE_ZONING")
    for lyr in arcpy.mapping.ListLayers(mxd) [0]:
        if lyr.supports("DATASOURCE"):
            if lyr.name == "CITY LIMITS":
                lyr.replaceDataSource(r"C:\Users\talmeida\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog\DSD15_SQLEXPRESS.gds\TonyOneWay\TonyOneWay.DBO.Canyon_Features", "SHAPEFILE_WORKSPACE", "TonyOneWay.DBO.City_Limits")            
    print "Successfully updated data sources"
    mxd.save()



Error for the following code.

C:\GIS\MAPBOOK\Proposed Zoning Book//Proposed_ZoningMapBook_Page_1.mxd is being processed

Traceback (most recent call last):
  File "C:\GIS\Python Scripts\Change Data Source MXD 2.py", line 14, in <module>
    for lyr in arcpy.mapping.ListLayers(mxd)[0]:
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\utils.py", line 181, in fn_
    return fn(*args, **kw)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\mapping.py", line 1500, in ListLayers
    result = mixins.MapDocumentMixin(map_document_or_layer).listLayers(wildcard, data_frame)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 823, in listLayers
    layers = self.layers
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 683, in layers
    for frame in reversed(self.dataFrames):
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 695, in dataFrames
    return map(convertArcObjectToPythonObject, self.pageLayout.dataFrames)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 679, in pageLayout
    return convertArcObjectToPythonObject(self._mxd._arc_object.pageLayout)
AttributeError: 'unicode' object has no attribute '_arc_object'

0 Kudos