How to get workspace path for map in Pro

1435
6
Jump to solution
02-02-2023 10:44 AM
RonnieRichards
Occasional Contributor III

Hello,

Where in arcpy for ArcGIS Pro can you obtain the workspaces from the map or layers? I cannot find this property in documentation? Specially I am looking for the name and path of the SDE connection file. This was very helpful when resourcing maps as we use standardize SDE connection names so we migrate maps to other environments we easily find and replace the workspace connection locations  & names. 

In arcpy.mapping for layers in MXDs there is a property which returns the workspacePaths for the layer. The reference is below.

https://desktop.arcgis.com/en/arcmap/latest/analyze/arcpy-mapping/layer-class.htm

In the ArcGIS Pro this help has an example of using the updateConnectionProperties method. For Enterprise Geodatabases, how does one obtain this connection string so this can be achieved?

https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/updatingandfixingdatasources.htm

RonnieRichards_0-1675363383332.png

There is an info tip in the Layer help stating there is no reference to the .sde connection file.

https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/layer-class.htm

 

 

Tip:
Enterprise geodatabase layers in an ArcGIS Pro project
do not retain the path to the database connection file (.sde) 
that was used to create the layer.

 

 

Without the original workspacePath/connection string how is it possible to read the .SDE connections from the map and update them programmatically using updateConnectionProperties?

 

 

0 Kudos
1 Solution

Accepted Solutions
BlakeTerhune
MVP Regular Contributor

I used Describe

import arcpy
import os

def getWorkspaceInfo(map_layer):
    """Takes an input map layer object and returns a dictionary with workspace information.
    """
    try:
        # Get workspace of input map layer
        workspace_path = arcpy.Describe(map_layer).catalogPath
        # Walk up the catalogPath until it's at the connection file.
        while not workspace_path.endswith('.sde'):
            if workspace_path == os.path.dirname(workspace_path):
                # You've reached the end (beginning) of the path.
                raise OSError("This catalogPath does not have an sde connection file.")
            workspace_path = os.path.dirname(workspace_path)
        workspace_desc = arcpy.Describe(workspace_path)
        workspace_instance = workspace_desc.connectionProperties.instance
        workspace_version = workspace_desc.connectionProperties.version
        # Get only the portion of the instance after the last colon character.
        # This might not be necessary depending on your rdbms.
        workspace_instance = workspace_instance.rsplit(":", 1)[1]
        if workspace_instance and workspace_version:
            return {
                "workspace_path": workspace_path,
                "workspace_instance": workspace_instance,
                "workspace_version": workspace_version
            }
        else:
            # workspace_instance or workspace_version is missing.
            raise AttributeError(f"workspace_instance is {workspace_instance}; workspace_version is {workspace_version}")
    except Exception as e:
        raise arcpy.ExecuteError(
            f"Unable to get workspace instance and version from map_layer {map_layer.name}"
        ) from e


# Get workspace path to .sde file
workspace_info = getWorkspaceInfo(my_map_layer_obj)
workspace_path = workspace_info["workspace_path"]

 

View solution in original post

6 Replies
BlakeTerhune
MVP Regular Contributor

I used Describe

import arcpy
import os

def getWorkspaceInfo(map_layer):
    """Takes an input map layer object and returns a dictionary with workspace information.
    """
    try:
        # Get workspace of input map layer
        workspace_path = arcpy.Describe(map_layer).catalogPath
        # Walk up the catalogPath until it's at the connection file.
        while not workspace_path.endswith('.sde'):
            if workspace_path == os.path.dirname(workspace_path):
                # You've reached the end (beginning) of the path.
                raise OSError("This catalogPath does not have an sde connection file.")
            workspace_path = os.path.dirname(workspace_path)
        workspace_desc = arcpy.Describe(workspace_path)
        workspace_instance = workspace_desc.connectionProperties.instance
        workspace_version = workspace_desc.connectionProperties.version
        # Get only the portion of the instance after the last colon character.
        # This might not be necessary depending on your rdbms.
        workspace_instance = workspace_instance.rsplit(":", 1)[1]
        if workspace_instance and workspace_version:
            return {
                "workspace_path": workspace_path,
                "workspace_instance": workspace_instance,
                "workspace_version": workspace_version
            }
        else:
            # workspace_instance or workspace_version is missing.
            raise AttributeError(f"workspace_instance is {workspace_instance}; workspace_version is {workspace_version}")
    except Exception as e:
        raise arcpy.ExecuteError(
            f"Unable to get workspace instance and version from map_layer {map_layer.name}"
        ) from e


# Get workspace path to .sde file
workspace_info = getWorkspaceInfo(my_map_layer_obj)
workspace_path = workspace_info["workspace_path"]

 

RonnieRichards
Occasional Contributor III

Thank you @BlakeTerhune that was very quick and this is perfect!

I'll have to test but does describe work on broken data sources as well?

0 Kudos
BlakeTerhune
MVP Regular Contributor

I haven't tested it with broken data sources. I'm not sure how it would handle that.

0 Kudos
RonnieRichards
Occasional Contributor III

For some reason this Describe catalog path does not return the original SDE Connection used. The map document was authored using a UNC path with standardized names and a temporary .sde connection was returned. Does it return the expected .sde connection file name and path in your situation?

The map was authored with data from: \\servername\publish\readuser@prodDB_web_sde.sde\web_sde.GIS.COUNTY_BOUNDARY

The describe returns: C:\Users\username\AppData\Local\Temp\1\a2190f00b0450b088ca7cd2e92f9f4b5.sde\web_sde.GIS.COUNTY_BOUNDARY

This might be what that little tip was indicating in the layer help but this is not at all helpful if the sde connections are always in the local profile with the orignal naming destroyed. 

0 Kudos
BlakeTerhune
MVP Regular Contributor

That is my observation as well. It seems ArcGIS Pro makes some kind of temporary copy of the connection file while the app is open. However, I've been able to do everything I need with this connection file (short of knowing where the original sde file is).

0 Kudos
RonnieRichards
Occasional Contributor III

Thanks for the confirmation @BlakeTerhune ! Your solution is perfect to obtain a path to a .sde workspace. ArcGIS Pro seems to copy or create the sde connection into the local profile. It's unfortunate the original path was not preserved but maybe this was removed due to security or other issues if source connections are exposed. 

On this end, we will proceed with resourcing data on what exists in the connection properties. Thanks for your response to this