You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I had an issue with some old databases that was really hard to track down. It had to do with a faulty projection definition from a personal geodatabase created over a decade ago that had been converted to a file geodatabase. No need to go into too much detail, but I was only able to find the error by going back and "describing" each class in the database to get the projection details where I finally found the error.
After thinking about it some more, and to satisfy my quest to automate QC tasks, I decided getting a report about the structure of a database and its components (and I mean a really detailed report!) could be quite useful. So, I created a tool to make a report, making use of the excellent module already developed by Evan that's hiding within the GeMS utility functions called "gdb_object_dict". Again, no need to go into all the nuts and bolts, suffice to say this function returns a comprehensive description of the database in a machine readable collection of Python lists and dictionaries. All I did was take the output of the function and make it human-readable so anyone can use this powerful function to get a detailed report of all the items in a geodatabase or geopackage.
# GeMS_DescribeDatabase.py
# Andrew L. Wunderlich
# andrew.wunderlich@tn.gov
# 11/27/2023
"""
Uses the gdb_object_dict function of the GeMS_utilityFunctions to build a report of the contents
of a GeMS-style geodatabase or geopackage.
This tool reads the input geodatabase or geopackage and produces a report in the output window, optionally
writing the report to a text file. This script borrows code from the Create and Backup GeMS tool and relies
on the GeMS_utilityFunctions.py in the Resources folder of the GeMS toolbox to function.
Script setup for ArcGIS Pro toolbox:
Name: DescribeDatabase
Label: Describe (GeMS) Database
Description: This tool reads the input geodatabase or geopackage and produces a report in the output window,
optionally writing the report to a text file.
Store tool with relative path: YES
ArcGIS Pro Tool Properties required Parameters:
Input geodatabase or geopackage - Workspace; Required; Input
Write log file - Boolean; Optional; Input
Log file location - Folder; Optional; Input
Paste the following code into the Validation parameters replacing the default "def updateParameters(self)" section:
def updateParameters(self):
# Modify parameter values and properties.
# This gets called each time a parameter is modified, before
# standard validation.
if str(self.params[1].value).lower() == "true":
self.params[2].enabled = True
else:
self.params[2].enabled = False
self.params[2].value = ""
return
"""
import arcpy
import sys
import os
import datetime
import GeMS_utilityFunctions as GuF
# Presumptive GeMS git info
versionString = "GeMS_DescribeDatabase.py, version of 11/27/23"
# rawurl="https://raw.githubusercontent.com/DOI-USGS/gems-tools-pro/master/Scripts/GeMS_DescribeDatabase.py"
# checkVersion(versionString, rawurl, "gems-tools-pro")
GuF.addMsgAndPrint(versionString)
# Usage string
usage = """
Usage: GeMS_DescribeDatabase.py <Input geodatabase or geopackage> <Write log file> <Log file location>
<Input geodatabase or geopackage> is a geodatabase or geopackage (NOT modified by the tool).
<Write log file> boolean (True/False with or without quotes) that determines if the tool
will write to a log file (True) or not (False; default).
<Log file location> folder location to store the log file.
"""
try:
# Create a list to store the log results
logResults = [versionString]
# Function to create file name for output text file. Code borrowed from GeMS Compact and Backup script w/ ALW mods
def logName(inDb,outFolder):
# returns name for the contents of the log file where
# inDb is of type (.gdb or .gpkg)
# name is of form inDb_contents_yyyy-mm-dd[x].txt
# where x is '', then 'b', 'c', 'd'...
# and logName doesn't yet exist
if len(outFolder) < 3:
nameRoot = os.path.splitext(inDb)[0]
else:
nameRoot = outFolder + "\\" + os.path.splitext(os.path.basename(inDb))[0]
nameSfx = ".txt"
nameInc = " bcdefghijklmnopqrstuvwxyz"
date = datetime.datetime.now().strftime("%Y-%m-%d")
newName = nameRoot + "_contents_" + date + nameSfx
i = 0
while arcpy.Exists(newName):
i = i + 1
newName = nameRoot + "_contents_" + date + nameInc[i] + nameSfx
if i > 25:
return ""
return newName
### Gather info from user inputs
# Input geodatabase or geopackage
gdb = sys.argv[1]
# Check if user wants to write to log file
if sys.argv[2].lower() == "true":
writeLog = True
else:
writeLog = False
# Set up log file to write to
logLocation = ""
if len(sys.argv[3]) > 3:
logLocation = sys.argv[3]
### Begin creating the report
# Set the workspace
arcpy.env.workspace = gdb
# Inventory gdb using gdb_object_dict from the GeMS utility functions
d = GuF.gdb_object_dict(gdb)
# Print out contents of database dict inventory
# This does a nice job of printing contents of a GeMS gdb in a human-readable form
GuF.addMsgAndPrint("Contents of the geodatabase " + gdb)
# Append each msg to the LogResult list
logResults.append("Contents of the geodatabase " + str(gdb))
for k, v in d.items():
GuF.addMsgAndPrint(str(k) + ":")
logResults.append(str(k) + ":")
for x, y in v.items():
if x == "fields":
fields = [f.name for f in y]
GuF.addMsgAndPrint(" fields: " + str(fields))
logResults.append(" fields: " + str(fields))
elif x == "indexes":
indexes = [i.name for i in y]
GuF.addMsgAndPrint(" indexes: " + str(indexes))
logResults.append(" indexes: " + str(indexes))
elif x == "spatialReference":
spRef = y
GuF.addMsgAndPrint(" spatialReference: WKID " + str(spRef.factoryCode) + "; " + str(spRef.name))
logResults.append(" spatialReference: WKID " + str(spRef.factoryCode) + "; " + str(spRef.name))
elif x == "children":
try:
# This works if the children are a simple list
children = [c.name for c in y]
GuF.addMsgAndPrint(" children: " + str(children))
logResults.append(" children: " + str(children))
except AttributeError:
# This only happens when there is a dictionary within the dictionary (FDatasets)
GuF.addMsgAndPrint(" children: FEATURE DATASET CHILD ITEMS ARE DISPLAYED INDIVIDUALLY")
logResults.append(" children: FEATURE DATASET CHILD ITEMS ARE DISPLAYED INDIVIDUALLY")
except:
# This shouldn't happen, but will handle anything else...
GuF.addMsgAndPrint(" UNABLE TO PRINT CHILD ITEMS OF: " + str(x))
logResults.append(" UNABLE TO PRINT CHILD ITEMS OF: " + str(x))
else:
GuF.addMsgAndPrint(" " + str(x) + ": " + str(y))
logResults.append(" " + str(x) + ": " + str(y))
# Write the contents of the database to a txt file
if writeLog:
try:
# Get the name of the log file
logFile = logName(gdb, logLocation)
logDate = datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
GuF.addMsgAndPrint("Log file written to " + logFile)
logResults.append("Log file written to " + logFile + "; Date_time: " + logDate)
lF = open(logFile, "w", encoding="utf8")
i = 0
while i < len(logResults):
lF.write(logResults[i] + "\n")
i += 1
lF.close()
GuF.addMsgAndPrint("Log file written successfully!")
except FileNotFoundError:
GuF.addMsgAndPrint("Invalid log file name or location")
except:
GuF.addMsgAndPrint("An error occurred, please check usage and try again:")
GuF.addMsgAndPrint(usage)
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I had an issue with some old databases that was really hard to track down. It had to do with a faulty projection definition from a personal geodatabase created over a decade ago that had been converted to a file geodatabase. No need to go into too much detail, but I was only able to find the error by going back and "describing" each class in the database to get the projection details where I finally found the error.
After thinking about it some more, and to satisfy my quest to automate QC tasks, I decided getting a report about the structure of a database and its components (and I mean a really detailed report!) could be quite useful. So, I created a tool to make a report, making use of the excellent module already developed by Evan that's hiding within the GeMS utility functions called "gdb_object_dict". Again, no need to go into all the nuts and bolts, suffice to say this function returns a comprehensive description of the database in a machine readable collection of Python lists and dictionaries. All I did was take the output of the function and make it human-readable so anyone can use this powerful function to get a detailed report of all the items in a geodatabase or geopackage.
Beta Was this translation helpful? Give feedback.
All reactions