I created this script to help with some geodatabase house cleaning tasks. Maybe someone else will find it useful or have an idea to improve it.
import arcpy import os # Set workspace myGDB = r"C:\temp\working.gdb" # Get domains that are assigned to a field domains_used = [] for dirpath, dirnames, filenames in arcpy.da.Walk(myGDB, datatype=["FeatureClass", "Table"]): for filename in filenames: print "Checking {}".format(os.path.join(dirpath, filename)) try: ## Check for normal field domains for field in arcpy.ListFields(os.path.join(dirpath, filename)): if field.domain: domains_used.append(field.domain) ## Check for domains used in a subtype field subtypes = arcpy.da.ListSubtypes(os.path.join(dirpath, filename)) for stcode, stdict in subtypes.iteritems(): if stdict["SubtypeField"] != u'': for field, fieldvals in stdict["FieldValues"].iteritems(): if not fieldvals[1] is None: domains_used.append(fieldvals[1].name) except Exception, err: print "Error:", err # Get domains that exist in the geodatabase domains_existing = [dom.name for dom in arcpy.da.ListDomains(myGDB)] # Find existing domains that are not assigned to a field domains_unused = set(domains_existing) ^ set(domains_used) print "{} unused domains in {}".format(len(domains_unused), myGDB) for domain in domains_unused: arcpy.DeleteDomain_management(myGDB, domain) print "{} deleted".format(domain)
This is great. But I have a problem deleting Domains in SDE where I'm not the owner. The owner is long gone and I can't delete domains even tough I'm sa on the SQL instance! Anyone run into this on SDE?
When you say the owner is long gone, do you mean the user account was deleted?
That is correct. Domains in SDE (Enterprise Database) are owned by the user who created them. A domain can be created explicated or gets created when the feature class with domains is copied into the SDE geodatabase. So, I have domains owned by kreuzrsk and some owned by and others owned by DBO. Since, I'm not DBO I can't delete those or any others ones I don't own.
You'll need to contact the people who can log in as those users to help you out. If they aren't around any more, you may be able to create the account again and use it to delete the domains owned by that person. If their account is still there but the person has left, just reset their password, connect with their account, complete your maintenance, then delete the account.
This is an excellent script. I used it on an Enterprise SQL Geodatabase by only changing the db connection. Thanks Blake!
This is very helpful. Thank you for sharing!
I've used this script for ArcSDE. At first run, it deleted 14 unused domains. Then it showed me runtime error.
At second run, it deleted one unused domain. Then I've encountered the same runtime error again. See below error message.
Runtime error Traceback (most recent call last): File "<string>", line 34, in <module> File "c:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\management.py", line 1462, in DeleteDomain raise e ExecuteError: ERROR 999999: Error executing function. The domain is used as a default domain. Failed to execute (DeleteDomain).
Do you have any idea what's wrong? Thank you in advance!
Hi Heena,
A domain you're trying to delete can't be deleted as long as it is a domain still in use. You'll have to identify which feature class and/or table fields are set to use that domain. Then delete that association before you run the delete.
According to Esri documentation, it does indeed mean the domain is already used somewhere. It also means that there's some case where the code is getting a false positive that the domain is unused or else it shouldn't be trying to delete it. If you comment out the line that attempts to delete the domain
arcpy.DeleteDomain_management(myGDB, domain)
it will just print the domain that should be deleted. It's possible that domain is used in a subtype and the code is somehow working incorrectly in that case. I may not have fully tested with subtypes.
After commenting out "arcpy.DeleteDomain_management(myGDB, domain)", the script has found the rest of domains that are not used. This helps a lot. Thank you for your help Blake and Randy!
Based off your original post, how would I modify the script so that it can be converted to a tool, with the input being any user defined sde database, and the output being a message with the 'domains_unused'
Here's what I have so far.....it works as a tool, but I do not see the print messages being output under geoprocessing results or some sort of text file message:
import arcpy
import os
#Slightly modified from Geonet thread by Blake Terhune titled 'Delete Unused Domains'
# Set workspace
arcpy.env.workspace = arcpy.GetParameterAsText(0)
# Get domains that are assigned to a field
domains_used = []
for dirpath, dirnames, filenames in arcpy.da.Walk(myGDB, datatype=["FeatureClass", "Table"]):
for filename in filenames:
print "Checking {}".format(os.path.join(dirpath, filename))
try:
## Check for normal field domains
for field in arcpy.ListFields(os.path.join(dirpath, filename)):
if field.domain:
domains_used.append(field.domain)
## Check for domains used in a subtype field
subtypes = arcpy.da.ListSubtypes(os.path.join(dirpath, filename))
for stcode, stdict in subtypes.iteritems():
if stdict["SubtypeField"] != u'':
for field, fieldvals in stdict["FieldValues"].iteritems():
if not fieldvals[1] is None:
domains_used.append(fieldvals[1].name)
except Exception, err:
print "Error:", err
# Get domains that exist in the geodatabase
domains_existing = [dom.name for dom in arcpy.da.ListDomains(myGDB)]
# Find existing domains that are not assigned to a field
domains_unused = set(domains_existing) ^ set(domains_used)
print "{} unused domains in {}".format(len(domains_unused), myGDB)
print domains_unused