0

I have a geodatabase that has multiple domains (50 +) and I want to assign them to specific feature class fields (there's over 50 feature classes) in an automated way because I'd like to run this script on a nightly basis.

For example, I have a feature class named "Hydrant" and two domains (Hyd_MAKE, Hyd_SIZE) that I want to assign to the "Hydrant" feature class fields "Make" and "Size" respectively. In addition to the "Hydrant" feature class, I have several other feature class fields (around 50 feature classes) that I want to assign other domains to. Is there a Python script that I can write to accomplish this or should I go with another route?

I know I can use AssignDomainToField to assign domains to a feature class field but I want to automate this with a For Loop or some other iterative process; That hasn't been working out too well.

Here is what I have so far (I am open to a completely different direction; this is just what I originally thought of):

import arcpy
aWS = r"GDBPath"
arcpy.env.workspace = aWS
arcpy.env.overwriteOutput = True

# Assign domain to field
fcList = arcpy.ListFeatureClasses()

for fc in fcList:
    print fc

    fields = arcpy.ListFields(fc)
    for field in fields:
        print "Field: " + field.name


        # Hydrant feature
        if fc == "Hydrant":
            fh = fc

            # name of fields
            f_fh_list = ["Make", "Size"]
            f_fh_list.sort()
            for f_fh in f_fh_list:
                print f_fh

                domains = arcpy.da.ListDomains()
                ##Loop through all domains
                for domain in domains:
                    fh_dn = domain.name
                    fh_dom_list = ["Hyd_MAKE","Hyd_SIZE"]
                    fh_dom_list.sort()
                    if fh_dn in fh_dom_list:
                        arcpy.AssignDomainToField_management(fh, f_fh, fh_dn)

                else:
                     print "Next domain"

        else:
            print "Next feature
4
  • 1
    If you know the feature class, field, and domain name, a python script can be used to attach domains to fields. I'm unsure why you'd need to run it nightly though - you should only need to run it once.
    – Midavalo
    Commented Jun 3, 2016 at 19:52
  • I am running a script that creates domains from Oracle Look up tables and sometimes coded domain values are added throughout the week so I want to capture those changes. The script in this question is a second component to that script where I want to assign the domains to fields.
    – Djb
    Commented Jun 3, 2016 at 20:29
  • Why not modify the existing, already attached, domains? These can be modified in place without having to remove or reattach to fields
    – Midavalo
    Commented Jun 3, 2016 at 20:30
  • The code above was my first attempt at this but it doesn't seem very efficient and I was wondering if someone would do this differently?
    – Djb
    Commented Jun 3, 2016 at 20:32

1 Answer 1

2

The following should do it. Create a dictionary that contains your feature class names, and a dictionary of the fields and domain names e.g.

fieldDomains = {'Hydrant': {'Make': 'Hyd_MAKE', 'Size': 'Hyd_Size'}}

This is then checked against feature classes and fields to assign the correct domain to each field.

The script loops through each feature class, and if it exists in the dictionary it then loops through each field. If those fields exist in the feature class dictionary it checks for existing domain and attaches to the field if found.

Using this then all you need to update is the dictionary when you add feature classes, fields, and domains to your GDB. The script will just update anything that matches values in the dictionary.

import arcpy
aWS = r"GDBPath"
arcpy.env.workspace = aWS
arcpy.env.overwriteOutput = True

# Dictionary of your feature classes, fields, and domains
fieldDomains = {'Hydrant': {'Make': 'Hyd_MAKE', 'Size': 'Hyd_Size'}}

# Assign domain to field
fcList = arcpy.ListFeatureClasses()

existingDomains = set(x.name for x in arcpy.da.ListDomains())

for fc in fcList:
    if fc in fieldDomains:
        print "Feature Class: {}".format(fc)
        domainDict = fieldDomains[fc]
        fields = arcpy.ListFields(fc)
        for field in fields:
            print "\tField: {}".format(field.name)
            if field.name in domainDict and domainDict[field.name] in existingDomains:
                print "\t\tAttaching domain {} to {}".format(domainDict[field.name], field.name)
                arcpy.AssignDomainToField_management(fc, field.name, domainDict[field.name])
            else:
                print "\t\tNo domain to add"

Possibly the largest performance/efficiency gain is that it only lists domains once, as domains are held at GDB level so you don't need to list it for each feature class or field as in your original script.


To update your fieldDomains with new feature classes, fields etc., just add them into the dictionary:

fieldDomains = {'Hydrant': {'Make': 'Hyd_MAKE', 'Size': 'Hyd_Size'},
                'Pump': {'Make': 'Pump_MAKE', 'Type': 'Pump_Type'},
                'Valve': {'Make': 'Valve_MAKE', 'Type': 'Valve_TYPE', 'Size': 'Valve_SIZE'} }

I always find it clearer to keep each one on separate lines - if they're within the { } they'll be included in the one dictionary.

2
  • Great - this is what I was looking for. How do I add another feature class/field/domain to the dictionary? 'fieldDomains = {'Hydrant': {'Make': 'Hyd_MAKE', 'Size': 'Hyd_Size'}}, {'Pump': {'Make': 'Pump_MAKE', 'Type': 'Pump_Type'}}' ?
    – Djb
    Commented Jun 3, 2016 at 23:20
  • 1
    @Djb almost - I have updated my answer to explain how to update it. You can see from my extra 'Valves' that you can include extra fields in there as well, as required.
    – Midavalo
    Commented Jun 3, 2016 at 23:25

Not the answer you're looking for? Browse other questions tagged or ask your own question.