Pro:How to check if domain exists, if not, do something else skip

3983
13
06-10-2018 11:35 AM
ThomasColson
MVP Frequent Contributor

I'm attempting to use py to check if a domain exists, if not, create it, else do nothing. After consulting How do I check if a domain already exists? , arcgis 10.0 - Using arcpy.Exists for domains? - Geographic Information Systems Stack Exchange , and esri geodatabase - Checking if domain already exists using ArcPy? - Geographic Information Systems S... I came up with the attached code. If neither domain exists, it fails with:

Start Time: Sunday, June 10, 2018 2:28:13 PM
Running script Add Extended Core Fields...
Failed script Add Extended Core Fields...
Traceback (most recent call last):
 File "C:\Temp\PRO_FOLDER_STRUCTURE\EXTENDED_CORE_FIELDS.py", line 24, in <module>
 arcpy.CreateDomain_management(gdb_name, "DOM_YES_NO_UNK_NPS2016", "Is the feature physically observable", "TEXT", "CODED")
 File "c:\program files\arcgis\pro\Resources\arcpy\arcpy\management.py", line 1332, in CreateDomain
 raise e
 File "c:\program files\arcgis\pro\Resources\arcpy\arcpy\management.py", line 1329, in CreateDomain
 retval = convertArcObjectToPythonObject(gp.CreateDomain_management(*gp_fixargs((in_workspace, domain_name, domain_description, field_type, domain_type, split_policy, merge_policy), True)))
 File "c:\program files\arcgis\pro\Resources\arcpy\arcpy\geoprocessing\_base.py", line 496, in <lambda>
 return lambda *args: val(*gp_fixargs(args, True))
arcgisscripting.ExecuteError: Failed to execute. Parameters are not valid.
 ERROR 000192: Invalid value for Domain Name
Failed to execute (CreateDomain).
 Failed to execute (AddExtendedCoreFields).
Failed at Sunday, June 10, 2018 2:28:14 PM (Elapsed Time: 1.52 seconds)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

However it creates the domain!

If I run it again knowing the domain exists, same error message. 

import os
import errno
import arcpy
#Get user input
gdb_name = arcpy.GetParameterAsText(0)
fc_name = arcpy.GetParameterAsText(1)
isOBSERVABLEchecked = arcpy.GetParameterAsText(2)
isISEXTANTchecked = arcpy.GetParameterAsText(3)





#Create the Optional OBSERVABLE domain

if str(isOBSERVABLEchecked) == 'true':
        existingDomains = arcpy.da.ListDomains(gdb_name)
        isthere = False
        for domain in existingDomains:
                if domain.name == 'DOM_YES_NO_UNK_NPS2016':
                        isthere = True
                        break
                if isthere == False:
                        arcpy.CreateDomain_management(gdb_name, "DOM_YES_NO_UNK_NPS2016", "Is the feature physically observable", "TEXT", "CODED")
                        YESNODict = {"Unknown":"Unknown", "Yes": "Yes", "No": "No"}
                        for code in YESNODict:        
                                arcpy.AddCodedValueToDomain_management(gdb_name, "DOM_YES_NO_UNK_NPS2016", code, YESNODict[code])
                else:
                        arcpy.AddMessage("DOM_YES_NO_UNK_NPS2016 already exists")
                        


#Create the Optional ISEXTANT domain
if str(isISEXTANTchecked) == 'true':
        existingDomains = arcpy.da.ListDomains(gdb_name)
        isthere = False
        for domain in existingDomains:
                if domain.name == 'DOM_YES_NO_UNK_NPS2016':
                        isthere = True
                        break
                if isthere == False:
                                arcpy.CreateDomain_management(gdb_name, "DOM_ISEXTANT_NPS2016", "Indicates feature or features that are no longer in existence or partially in existence.", "TEXT", "CODED")
                                ISEXTANTDict = {"Unknown":"Unknown", "True": "True", "False": "False", "Partial": "Partial", "Other": "Other"}
                                for code in ISEXTANTDict:        
                                        arcpy.AddCodedValueToDomain_management(gdb_name, "DOM_ISEXTANT_NPS2016", code, ISEXTANTDict[code])

                else:
                        arcpy.AddMessage("DOM_ISEXTANT_NPS2016 already exists")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

As best as I can tell, I have an illegal loop condition that keeps trying to create the first domain whether it exists or not, and the failure stems from the domain name already exists. 

0 Kudos
13 Replies
DanPatterson_Retired
MVP Emeritus

A quick look

You might use a 'try except' block.  If you 'try' to see if it exists and it fails, it will go to the except block (there are variants like try-except-else-finally

0 Kudos
ThomasColson
MVP Frequent Contributor

Dan, with something like below, I'm getting nothing....

import os
import errno
import arcpy
#Get user input
gdb_name = arcpy.GetParameterAsText(0)
isOBSERVABLEchecked = arcpy.GetParameterAsText(1)
isISEXTANTchecked = arcpy.GetParameterAsText(2)




try:
        
        #Create the Optional OBSERVABLE field

        if str(isOBSERVABLEchecked) == 'true':
                existingDomains = arcpy.da.ListDomains(gdb_name)
                isthere = False
                for domain in existingDomains:
                        if domain.name == 'DOM_YES_NO_UNK_NPS2016':
                                isthere = True
                                break
                        if isthere == False:
                                arcpy.CreateDomain_management(gdb_name, "DOM_YES_NO_UNK_NPS2016", "Is the feature physically observable", "TEXT", "CODED")
                                YESNODict = {"Unknown":"Unknown", "Yes": "Yes", "No": "No"}
                                for code in YESNODict:        
                                        arcpy.AddCodedValueToDomain_management(gdb_name, "DOM_YES_NO_UNK_NPS2016", code, YESNODict[code])
                                #arcpy.AddField_management(fc_name, "OBSERVABLE", "TEXT", "", "", 20, "OBSERVABLE", "NULLABLE", "NON_REQUIRED", "DOM_YES_NO_UNK_NPS2016")
                                #arcpy.AssignDefaultToField_management(fc_name, "OBSERVABLE", "Unknown")
                        else:
                                arcpy.AddMessage("DOM_YES_NO_UNK_NPS2016 already exists")
                                

        else:
                arcpy.AddMessage("OBSERVABLE field not created")

        #Create the Optional ISEXTANT field
        if str(isISEXTANTchecked) == 'true':
                existingDomains = arcpy.da.ListDomains(gdb_name)
                isthere = False
                for domain in existingDomains:
                        if domain.name == 'DOM_YES_NO_UNK_NPS2016':
                                isthere = True
                                break
                        if isthere == False:
                                        arcpy.CreateDomain_management(gdb_name, "DOM_ISEXTANT_NPS2016", "Indicates feature or features that are no longer in existence or partially in existence. If data represents features that are no longer in existence or only partially in existence following damage, disaster or some other change to its statusthen the value will be false or partial (Cultural Resources, 2014).", "TEXT", "CODED")
                                        ISEXTANTDict = {"Unknown":"Unknown", "True": "True", "False": "False", "Partial": "Partial", "Other": "Other"}
                                        for code in ISEXTANTDict:        
                                                arcpy.AddCodedValueToDomain_management(gdb_name, "DOM_ISEXTANT_NPS2016", code, ISEXTANTDict[code])
                                        #arcpy.AddField_management(fc_name, "ISEXTANT", "TEXT", "", "", 20, "ISEXTANT", "NULLABLE", "NON_REQUIRED", "DOM_ISEXTANT_NPS2016")
                                        #arcpy.AssignDefaultToField_management(fc_name, "ISEXTANT", "Unknown")

                        else:
                                arcpy.AddMessage("DOM_ISEXTANT_NPS2016 already exists")
                                

        else:
                arcpy.AddMessage("ISEXTANT field not created")

except arcpy.ExecuteError:
    print(arcpy.GetMessages(2))     
0 Kudos
DanPatterson_Retired
MVP Emeritus

not sure why you have a break on line 41 I would suspect you would want to continue your checks.  And on line 42, it is generally not recommended to do an equality check for booleans.  Just use

if isthere:   # is it there  This is the True case  

or

if not isthere:  # this is the False case

It reads better if you use 'present'  then you get 'if present: ' and 'if not present'

0 Kudos
ThomasColson
MVP Frequent Contributor

Dan not sure what you meant in above (I didn't take your Python class!), but this is what I think you meant, which, creates the domain if it doesn't exist, but if the domain exists, just runs successfully with no exit reporting domain already exists....

import os
import errno
import arcpy
#Get user input
gdb_name = arcpy.GetParameterAsText(0)
isOBSERVABLEchecked = arcpy.GetParameterAsText(1)

try:
        
        #Create the Optional OBSERVABLE field

        if str(isOBSERVABLEchecked) == 'true':
                existingDomains = arcpy.da.ListDomains(gdb_name)
                isthere = False
                for domain in existingDomains:
                        if domain.name == 'DOM_YES_NO_UNK_NPS2016':
                                isthere = True
                        if isthere == False:
                                arcpy.CreateDomain_management(gdb_name, "DOM_YES_NO_UNK_NPS2016", "Is the feature physically observable", "TEXT", "CODED")
                                YESNODict = {"Unknown":"Unknown", "Yes": "Yes", "No": "No"}
                                for code in YESNODict:        
                                        arcpy.AddCodedValueToDomain_management(gdb_name, "DOM_YES_NO_UNK_NPS2016", code, YESNODict[code])
                                #arcpy.AddField_management(fc_name, "OBSERVABLE", "TEXT", "", "", 20, "OBSERVABLE", "NULLABLE", "NON_REQUIRED", "DOM_YES_NO_UNK_NPS2016")
                                #arcpy.AssignDefaultToField_management(fc_name, "OBSERVABLE", "Unknown")
                        else:
                                arcpy.AddMessage("DOM_YES_NO_UNK_NPS2016 already exists")
                                

        else:
                arcpy.AddMessage("OBSERVABLE domain not created")


except arcpy.ExecuteError:
    print(arcpy.GetMessages(2))            
0 Kudos
DanPatterson_Retired
MVP Emeritus

At this stage, I would put in as many print statements as you can muster, since nothing is throwing an error, but you don't know if it doing nothing or not getting to where something is being done

ThomasColson
MVP Frequent Contributor

In trying to isolate what's not working, I get this far. I've not set up the loop correctly...?I just want to check if the condition exists, print "exists", else print "it doesn't exist", where the condition is being checked against a list of domains:

for domain in existingDomains:
        if domain.name == 'DOM_YES_NO_UNK_NPS2016':
                print("DOM_YES_NO_UNK_NPS2016 already exists")
        else:
                print("creating domain")

                
creating domain
creating domain
creating domain
creating domain
creating domain
DOM_YES_NO_UNK_NPS2016 already exists
0 Kudos
DanPatterson_Retired
MVP Emeritus

Thomas... let's collect information on bit at a time.

  • since nothing is throwing an error, dump the try except block
  • existingDomains = arcpy.da.ListDomains(gdb_name)
  • domain_names = [i.name for i in existingDomains]
  • print(domain_names)

what does that print?

ThomasColson
MVP Frequent Contributor

['DOM_REGIONCODE_NPS2016', 'DOM_PUBLICDISPLAY_NPS2016', 'DOM_DATAACCESS_NPS2016', 'DOM_XYACCURACY_NPS2016', 'DOM_YEffS_NO_UNK_NPS2016', 'DOM_YES_NO_UNK_NPS2016']

Which is the same as 

for domain in existingDomains:
print(domain.name)

0 Kudos
RandyBurton
MVP Alum

You are looping through all domain names (around line 18 - for domain in existing...) and, since some of them will not match (at the next line), it will try to insert the new domain anyway.

Try setting up your loop like this:

gdb_name = r"C:\Path\To\file.gdb"
chkDomains = [
             ['DOM_YES_NO_UNK_NPS2016', {"Unknown":"Unknown", "Yes": "Yes", "No": "No"} ],
             ['DOM_ISEXTANT_NPS2016', {"Unknown":"Unknown", "True": "True", "False": "False", "Partial": "Partial", "Other": "Other"} ]
             ]

existingDomains = arcpy.da.ListDomains(gdb_name)
dn = []
for domain in existingDomains: # get list of domain names
    dn.append(domain.name)

for chk in chkDomains:
    if chk[0] in dn: # see if it is in list of domain names
        print "Domain {} exists".format(chk[0])
    else:
        print "Adding domain {} using dictionary {}".format(chk[0], chk[1])‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍