Trying to use if/elif logic to update mxd's of varying data sources

1314
7
05-22-2017 12:45 PM
petegillard
New Contributor III

I'm trying to update a number of mxd's from a variety of software versions/ folder/server locations/ ArcGIS server (i.e. ArcGIS 9.2 - 10.5). I can get it to work if I do them separately (the 9.2 gdb to sde, or 10.3 to 10.5 on different servers). It crashes when I threw them altogether (thought it would just ignore paths not relevant, but it doesn't (ALSO ! seems to crash if there's an esri basemap in the mxd?!). so thought I'd try an if/elif logic, but can't get it to read the workspace for the layer (as in: for ly in layer:

               if ly.something(?).. == some path:

                    findAndReplaceWorkspacePaths (or replaceWorkspaces) )

Any ideas would be helpful.

thanks,

Pete

0 Kudos
7 Replies
IanMurray
Frequent Contributor

Your questions is extremely broad and you aren't posting any code so it is difficult to respond adequately to you.

As far as the ESRI basemaps, they are web services and several layer properties are not supported for web service layers.  There is the support() method which can be use to test if a map layer supports a certain property and will likely be needed in order to have whatever script you are wishing to develop to ignore web service layers.

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

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

As far as logic to seperate out different versions of ArcMap Map Documents, you can see this thread here

https://gis.stackexchange.com/questions/62090/arcpy-method-to-determine-arcmap-document-version

If you give more information, especially with the types of errors you are getting it would help us help you.

petegillard
New Contributor III

Thanks to both. I have tried the dataSource property, but there are multiple feature classes within the sde geodatabase, and it works fine with findAndReplaceWorkspacePaths, and/or replaceWorkspaces. code below: and in the "if la.(something) =="  part it trips it up and won't work when it comes across a different workspace (hence the attempt at an if/elif approach)

lyr = arcpy.mapping.ListLayers(mxd)

for la in lyr:
        if la.workspace == r"Y:\arc.data\gdb92\GIS_layers.gdb":
            mxd.replaceWorkspaces(r"Y:\arc.data\gdb92\GIS_layers.gdb","FILEGDB_WORKSPACE", r"Database Connections\GIS_Base_Layers.sde","SDE_WORKSPACE")
   
        elif la.arcpy.env.workspace == r"\\Pol-nrd-data02\gis_y\arc.data\gdb92\GIS_layers.gdb": 
   mxd.replaceWorkspaces(r"\\Pol-nrd-data02\gis_y\arc.data\gdb92\GIS_layers.gdb","FILEGDB_WORKSPACE", r"Database Connections\GIS_Base_Layers.sde","SDE_WORKSPACE")
  
        elif la.arcpy.env.workspace == r"Y:\arc.data\gdb92\GIS_layers.gdb":
            mxd.findAndReplaceWorkspacePaths(r"Y:\arc.data\gdb92\GIS_layers.gdb", r"Database Connections\GIS_Data.sde")
            mxd.findAndReplaceWorkspacePaths(r"Y:\arc.data\gdb92\GIS_layers.gdb", r"Database Connections\GIS_Base_Layers.sde")
   
        elif la.arcpy.env.workspace == r"C:\Users\pgillard\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog\POL-NRD-GIS-1_SQLEXPRESS.gds\GIS_Base_Layers":
            mxd.findAndReplaceWorkspacePaths(r"C:\Users\pgillard\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog\POL-NRD-GIS-1_SQLEXPRESS.gds\GIS_Base_Layers", r"Database Connections\GIS_Base_Layers.sde")
            mxd.findAndReplaceWorkspacePaths(r"C:\Users\pgillard\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog\POL-NRD-GIS-1_SQLEXPRESS.gds\GIS_Data", r"Database Connections\GIS_Data.sde")

hope this makes sense,

thanks

0 Kudos
IanMurray
Frequent Contributor

A few questions:

1. You are trying to change the workspace paths(path to the dataset) for a certain workspaces(i.e some of your layers will not change paths, but you want certain workspaces changed_?

2. Is the new workspace the same for each and every layer that is one of thsoe certain workspaces?

3. Why if you are working with layer properties, are you trying to replace workspaces for the entire mxd?  You should just want to change the layer path if it meets a criteria, or check a whole mxd for a certain path(s) and change them.  You are currently mixing and matching

If you know all the workspaces you need replaced and need them all to the new workspace, I would write them all to a list, then evaluate for that layer(la.workspace) is in that list, instead of using a bunch of conditional statements.  If so then change layer workspace path to the new one, if not skip it.  You can use the supports() method to check for web service layers as well and make sure their workspace path is not checked.

Also layers have no workspace property, its workspacePath(la.workspacePath)

0 Kudos
petegillard
New Contributor III

thanks again,

yes i am just trying to change the layer paths within an mxd, not the workspace for the mxd. I will try the 'supports' method, as one of the errors is "

NameError: The attribute 'workspacePath' is not supported on this instance of Layer." (get the same error sometimes with dataSource). I'm trying this on several older mxd's so paths, software versions etc. could be anything in the last 7 years (probably just re-do the map!)

I guess I thought the if/elif would bypass that if it wasn't relevant. Occasionally, ArcCatalog craps out completely, so I haven't been able to figure out what is causing that.

Again, I wrote a python script that will change the gdb92 workspaces (with replaceWorkspaces)

and one each for the \\pol-nrd-data02\.... and the "C:\Users\name\AppData..." and they work fine, was trying the if/elif to see if I could get it all in one script - so far no luck.

On a slightly different note, I haven't been able to use wildcards in the path so r"C:\Users\pgillard\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog\POL-NRD-GIS-1_SQLEXPRESS.gds\GIS_Base_Layers"  (where the name and version  could be anything) would work no matter what values were  used.

Thanks again for the ideas, i'll give them a shot.

Pete

0 Kudos
curtvprice
MVP Esteemed Contributor

For the good of the thread, here's a better formatting of the code

lyr = arcpy.mapping.ListLayers(mxd)

# sql db path is hard to read so set a variable
sql_db = (r"C:\Users\pgillard"
          r"\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog"
          r"\POL-NRD-GIS-1_SQLEXPRESS.gds")

for la in lyr:
    if la.workspace == r"Y:\arc.data\gdb92\GIS_layers.gdb":
        mxd.replaceWorkspaces(
             r"Y:\arc.data\gdb92\GIS_layers.gdb",
             "FILEGDB_WORKSPACE", 
             r"Database Connections\GIS_Base_Layers.sde",
             "SDE_WORKSPACE")
    elif la.arcpy.env.workspace == r"\\Pol-nrd-data02\gis_y\arc.data\gdb92\GIS_layers.gdb": 
        mxd.replaceWorkspaces(
            r"\\Pol-nrd-data02\gis_y\arc.data\gdb92\GIS_layers.gdb",
            "FILEGDB_WORKSPACE", 
             r"Database Connections\GIS_Base_Layers.sde",
             "SDE_WORKSPACE")
    elif la.arcpy.env.workspace == r"Y:\arc.data\gdb92\GIS_layers.gdb":
        mxd.findAndReplaceWorkspacePaths(
            r"Y:\arc.data\gdb92\GIS_layers.gdb", 
            r"Database Connections\GIS_Data.sde") 
        # the following will never do anything if the one above worked (!)
        mxd.findAndReplaceWorkspacePaths(
            r"Y:\arc.data\gdb92\GIS_layers.gdb", 
            r"Database Connections\GIS_Base_Layers.sde") 
    elif la.arcpy.env.workspace == sql_db + "\GIS_Base_Layers":
        mxd.findAndReplaceWorkspacePaths(
            sql_db + r"\GIS_Base_Layers", 
            r"Database Connections\GIS_Base_Layers.sde")
        mxd.findAndReplaceWorkspacePaths(
            sql_db + r"\GIS_Data", 
            r"Database Connections\GIS_Data.sde")
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I agree the .supports() method is totally the way to check whether what you're doing on a layer is legal.

supports (layer_property):
Not all layers support the same set of properties. The supports property can be used to test which properties a layer does support.

Layer—Help | ArcGIS Desktop 

DanPatterson_Retired
MVP Emeritus

In the arcpy mapping module, there is the layer class which has the datasource property which..

Returns the complete path for the layer's data source. It includes the workspacePath and the datasetName properties combined. Not all layers support the dataSource property (for example, annotation classes and web services), so it is good practice to test for this ahead of time using the supports method.

RebeccaStrauch__GISP
MVP Emeritus

For what it's worth, you might want to look at my post /blogs/myAlaskaGIS/2015/08/31/python-addin-for-data-inventory-and-broken-link-repair?sr=search&searc...‌  You can look at the code there.  i have tested it across multiple versins, but not sure if any were back to 9.x anymore.  You can do an inventory that will create an output of the broken links without changing anything, so that might be what you want.  Please test on a copy of the mxds and folders first.

0 Kudos