Python ListLayers mxd vs ListFeatureClasses sde and compare

2470
9
Jump to solution
04-17-2017 02:00 PM
MatthewDriscoll
MVP Alum

Using python how would I go about listing layers I have in a mxd and seeing which of these features are in or not in certain sde databases?

When I use ListLayers in the mxd I get whatever they are named (issue here would be if the name is changed).

When I use the ListFeatureClassess in the sde I get the database.domain.featureclass returned (here I could probably split the string). 

I am not sure the best practice to get the common denominator?

Is there an easier way of doing this?

0 Kudos
1 Solution

Accepted Solutions
RandyBurton
MVP Alum

From Layer Help:

print lyr.name, lyr.dataSource, lyr.datasetName‍‍‍‍‍‍‍

Also, you may have an indentation error on line 20-21.

View solution in original post

9 Replies
JoshuaBixby
MVP Esteemed Contributor

Can you share your code?

According to the ListLayers documentation:

Returns a Python list of Layer objects that exist within a map document (.mxd), a data frame within a map document, or layers within a layer (.lyr) file

You should be getting a list of layer objects, not a list of strings.  The __str__ special method of the Layer object is the name of the layer, hence printing the Layer object will just print its name. 

MatthewDriscoll
MVP Alum
import arcpy
arcpy.env.workspace = "Database Connections\SDE_Database.sde"
datasetList = arcpy.ListDatasets("*", "Feature")
datasetList.sort()
for dataset in datasetList:
 print dataset
 fcList = arcpy.ListFeatureClasses("*","",dataset)
 sorts = sorted(fcList, key=lambda v: v.lower())
 for fc in sorts:
 print fc

jfkslist = arcpy.ListFeatureClasses("*")
sorts = sorted(jfkslist, key=lambda v: v.lower())
for sort in sorts:
 print sort

mxd = arcpy.mapping.MapDocument(r"mxdpath/MXD.mxd")

for lyr in arcpy.mapping.ListLayers(mxd):
 if lyr.supports("DATASOURCE"):
 print lyr.name
0 Kudos
RandyBurton
MVP Alum

From Layer Help:

print lyr.name, lyr.dataSource, lyr.datasetName‍‍‍‍‍‍‍

Also, you may have an indentation error on line 20-21.

JoshuaBixby
MVP Esteemed Contributor

If you are looking to see if layers are mapped to certain SDE databases, I would look to the service properties of the layer.  If the layer supports "SERVICEPROPERTIES", then check the ServiceType to see if it is SDE.  Then, you can access all types of information about the SDE database and how it is being connected to.

>>> for layer in layers:
...     if (layer.supports("SERVICEPROPERTIES") and 
...         layer.serviceProperties["ServiceType"] == "SDE"):
...         print layer.serviceProperties['Service']
MatthewDriscoll
MVP Alum

I am not really interested seeing which server the layers are in, I am more interested in the name, more importantly it's name within a database.  

The problem I run into is when I list layers in the mxd it returns how it is named in the mxd not it's actual name in the database.  If I could get the native feature class name, I could achieve what I am trying to do.

When I list feature classes it returns the database and the version along with the feature class.  ie targetdatabase.currentversion.myfeatureclass  This I think I can handle by making it a string and split it.   

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

rvburton‌ is correct.  The datasetName property returns what you are after, you are confusing it for what the name property returns, which is the name of the layer file in the MXD.

MatthewDriscoll
MVP Alum

I see now.  I was getting an error thrown at me, but I had a service layer in the mxd it did not like.  Thank you for the help.

AlexanderBrown5
Occasional Contributor II

Matthew,

If you have a copy of all the MXDs, or have access to them on a shared network drive, you can do something like:

import arcpy, os
from arcpy import env

wrkspc = r'D:\Path_to_mxds'
env.workspace = wrkspc
workspaces = arcpy.ListWorkspaces("*", "Folder")

# print "** " + str(wrkspc) + " **"
mxdList = arcpy.ListFiles("*.mxd")

for mxd in mxdList:
    # print mxd
    mxdPath = wrkspc + os.sep + mxd
    print mxdPath
    mxdObject = arcpy.mapping.MapDocument(mxdPath)

    for lyr in arcpy.mapping.ListLayers(mxdObject):
        if lyr.supports("DATASOURCE"):
            print "Layer: " + lyr.name + "  Source: " + lyr.dataSource
        else:
            print lyr

    del mxdObject

Of course you can add additional libraries to write everything out to csv or another database table.

~Alex

MatthewDriscoll
MVP Alum

Thank you this is very helpful.

0 Kudos