Select to view content in your preferred language

batch domain list

265
3
01-26-2026 12:55 PM
rami_shah
Emerging Contributor

Hi folks,

I am looking for python script that extract all domains where 

code <> description 

from SDE(oracle) database. any sample code that I could reuse is greatly appreciated.

 

Ram

0 Kudos
3 Replies
DavidSolari
MVP Regular Contributor

The List Domains function is what you're looking for, this will work on any EGDB. The sample code on that page should get you started.

0 Kudos
AlfredBaldenweck
MVP Frequent Contributor

Something like this

egdb = r"GDB.sde"
badDomains = []

for dom in arcpy.da.ListDomains(egdb):
    if dom.domainType == "Range":
        continue
    for key in dom.codedValues:
        if key!= dom.codedValues[key]:
            badDomains.append(dom.name)
print("done")
print(badDomains)
0 Kudos
HaydenWelch
MVP Regular Contributor

NOTE: In your version, if a domain has multiple non-matching values, it is added multiple times.

You can also do this in a dictionary comprehension:

def bad_domain(dataset: str):
    from arcpy.da import ListDomains
    return {
        d.name: d 
        for d in ListDomains(dataset) 
        if d.domainType == 'CodedValue' 
        and not all(
            value_key == value_description 
            for value_key, value_description in d.codedValues.items()
        )
    }

 

I usually like to unroll these types of filters into multiple functions so it's clear exactly what checks are being made:

from typing import Any
from arcpy.da import Domain

def is_bad_values(val: dict[Any, str]):
    any(k != v for k, v in val.items())

def is_bad_domain(d: Domain):
    return d.domainType == 'CodedValue' and is_bad_values(d.codedValues)

def bad_domains(dataset: str):
    from arcpy.da import ListDomains
    return {d.name: d for d in ListDomains(dataset) if is_bad_domain(d)}

 

If you want to get REALLY re-usable, you can use a registration pattern:

from collections.abc import Callable
from functools import wraps
from typing import Any
from arcpy.da import Domain

type DomainValidator = Callable[[Domain], bool]

Validators: list[DomainValidator] = []

VALID = True
INVALID = False

def register_validator(func: DomainValidator):
    Validators.append(func)
    @wraps
    def _wrapper(*args: Any, **kwargs: Any):
        return func(*args, **kwargs)
    return _wrapper


@register_validator
def domain_value_check(d: Domain):
    if d.domainType == 'CodedValue' :
        if any(k != v for k, v in d.codedValues.items()):
            return INVALID
    return VALID

@register_validator
def domain_range_check(d: Domain):
    if d.domainType == 'Range':
        min, max = d.range
        if not isinstance(min, (int, float)):
            return INVALID
        if not isinstance(max, (int, float)):
            return INVALID
        if min < 0 or max > 100:
            return INVALID
    return VALID

def bad_domains(dataset: str, validators: list[DomainValidator]=Validators):
    from arcpy.da import ListDomains
    return {
        d.name: d 
        for d in ListDomains(dataset) 
        if any(validator(d) is INVALID for validator in validators)
    }

 

Now you can just add and remove validations as you please.

0 Kudos