Delete Unused Domains

15211
30
06-08-2015 11:50 AM
BlakeTerhune
MVP Regular Contributor

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)

python snippets

30 Replies
RandyKreuziger
Occasional Contributor III

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?

BlakeTerhune
MVP Regular Contributor

When you say the owner is long gone, do you mean the user account was deleted?

0 Kudos
RandyKreuziger
Occasional Contributor III

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. 

0 Kudos
BlakeTerhune
MVP Regular Contributor

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.

0 Kudos
RumikaChaudhry
New Contributor

This is an excellent script. I used it on an Enterprise SQL Geodatabase by only changing the db connection.  Thanks Blake!

HeenaLee
New Contributor III

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!

0 Kudos
RandyKreuziger
Occasional Contributor III

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.

0 Kudos
BlakeTerhune
MVP Regular Contributor

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.

HeenaLee
New Contributor III

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! 

0 Kudos
AndresCastillo
MVP Regular Contributor

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
0 Kudos