Hello all,
I have a script where I am parsing through all the MXD's on the server and getting the service properties of all the feature classes and writing to a csv file.
I am running into an issue in an else statement where it is UnboundLocalError: local variable 'db' referenced before assignment.
I have tried changing the indentation of the sequence and when I put that inside the else statement I only get the first MXD in the folder written to the csv.
Below is the script. Any help would be appreciated.
import arcpy, os, csv, socket
#Turn off ESRI geoprocessing logging so XML column does not fill up
arcpy.SetLogHistory(False)
arcpy.gp.overwriteOutput = True
ags = socket.gethostname()
print "ArcGISServer:" + ags
def main(folder, outputfile):
with open(outputfile, "wb") as f:
w = csv.writer(f)
header = ("MapDocument", "LayerName", "FeatureClass", "Database", "Server", "Version", "UserName", "Authentication", "ArcGISServer")
w.writerow(header)
rows = crawlmxds(folder)
w.writerows(rows)
def crawlmxds(folder):
for root, dirs, files in os.walk(folder):
for f in files:
if f.lower().endswith(".mxd"):
mxdName = os.path.splitext(f)[0]
mxdPath = os.path.join(root, f)
mxd = arcpy.mapping.MapDocument(mxdPath)
print mxdPath
print mxdName
for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.supports("DATASOURCE"):
dSource = str(lyr.dataSource)
if '.sde' in dSource:
fcName = dSource.split('.sde\\')
print "Layer Name: " + lyr.name
print "Feature Class: " + fcName[1]
elif '.gdb' in dSource:
fcName = dSource.split('.gdb\\')
print "Layer Name: " + lyr.name
print "Feature Class: " + fcName[1]
## if lyr.supports("definitionQuery"):
## dq = lyr.definitionQuery
## print "Definition Query: " + lyr.definitionQuery
## else:
## print "NA"
if lyr.supports("SERVICEPROPERTIES"):
if lyr.serviceProperties["ServiceType"] != "SDE":
print "Service Type: " + lyr.serviceProperties.get('ServiceType', 'N/A')
print " URL: " + lyr.serviceProperties.get('URL', 'N/A')
print " Connection: " + lyr.serviceProperties.get('Connection','N/A')
print " Server: " + lyr.serviceProperties.get('Server','N/A')
print " Cache: " + lyr.serviceProperties.get('Cache','N/A')
print " User Name: " + lyr.serviceProperties.get('UserName','N/A')
print " Password: " + lyr.serviceProperties.get('Password','N/A')
print ""
else:
print "Service Type: " + lyr.serviceProperties.get('Service Type', 'N/A')
db = lyr.serviceProperties.get('Database', 'N/A')
print " Database: " + lyr.serviceProperties.get('Database', 'N/A')
svr = lyr.serviceProperties.get('Server', 'N/A')
print " Server: " + lyr.serviceProperties.get('Server', 'N/A')
srvc = lyr.serviceProperties.get('Service', 'N/A')
print " Service: " + lyr.serviceProperties.get('Service', 'N/A')
ver = lyr.serviceProperties.get('Version', 'N/A')
print " Version: " + lyr.serviceProperties.get('Version', 'N/A')
un = lyr.serviceProperties.get('UserName', 'N/A')
print " User Name: " + lyr.serviceProperties.get('UserName', 'N/A')
auth = lyr.serviceProperties.get('Authentication', 'N/A')
print " Authentication: " + lyr.serviceProperties.get('Authentication', 'N/A')
print ""
seq = (mxdName, lyr.name, fcName[1], db, svr, ver, un, auth, ags);
yield seq
del mxd
if __name__ == "__main__":
folderPath = r"mxdpath" # or arcpy.GetParameterAsText(0)
output = r"csvpath" # or arcpy.GetParameterAsText(1)
main(folderPath, output)
Just glanced through, but you've not created the variables (db, svr...) to yield when the condition is met (not SDE) - only when SDE. A quick fix might be to assign them within that if true block - db = "None" ... etc.
Far from a coding whizz so take a big pinch of salt with that.
the variable/property "db" only gets a value in one case.
A safe way of finding out what is going on is to assign potential returns to some value, whether it be None prior to running any loops. For example
db = None; svr =None; ver = None; un = None; auth = None; ags = None
db = None; svr =None; ver = None; un = None; auth = None; ags = None
def crawlmxds(seq):
for i in seq:
print("{}".format(i))
seq = [db, svr, ver, un, auth, ags]
crawlmxds(seq)
None
None
None
None
None
None
Then when you see a None, you know something is wrong.
The alternative is check each variable assignment before you try to use it, as is your current case.
Thanks Dan and David! I took a look at both of your suggestions and what think I may have found a solution...however not the prettiest or most understandable but if I put the variables after the Service Type variable like below it works.
if lyr.supports("SERVICEPROPERTIES"):
if lyr.serviceProperties["ServiceType"] != "SDE":
db = lyr.serviceProperties.get('Database', 'N/A')
print " Database: " + lyr.serviceProperties.get('Database', 'N/A')
svr = lyr.serviceProperties.get('Server', 'N/A')
print " Server: " + lyr.serviceProperties.get('Server', 'N/A')
srvc = lyr.serviceProperties.get('Service', 'N/A')
print " Service: " + lyr.serviceProperties.get('Service', 'N/A')
ver = lyr.serviceProperties.get('Version', 'N/A')
print " Version: " + lyr.serviceProperties.get('Version', 'N/A')
un = lyr.serviceProperties.get('UserName', 'N/A')
print " User Name: " + lyr.serviceProperties.get('UserName', 'N/A')
auth = lyr.serviceProperties.get('Authentication', 'N/A')
print " Authentication: " + lyr.serviceProperties.get('Authentication', 'N/A')
print "Service Type: " + lyr.serviceProperties.get('ServiceType', 'N/A')
print " URL: " + lyr.serviceProperties.get('URL', 'N/A')
print " Connection: " + lyr.serviceProperties.get('Connection','N/A')
print " Server: " + lyr.serviceProperties.get('Server','N/A')
print " Cache: " + lyr.serviceProperties.get('Cache','N/A')
print " User Name: " + lyr.serviceProperties.get('UserName','N/A')
print " Password: " + lyr.serviceProperties.get('Password','N/A')
print ""
else:
print ""
seq = (mxdName, lyr.name, fcName[1], db, svr, ver, un, auth, ags);
yield seq