List all coded and range values by domain group to table

779
3
Jump to solution
01-12-2023 07:49 PM
Jen_Zumbado-Hannibal
Occasional Contributor

Hello, 

I'm not a programmer so forgive my ignorance ahead of time. 

I want to extract a list of ALL the domains within SDE and group them by name with their corresponding coded or range values. 

So far I've done it using Notebook and IDLE. 

However, I don't know exactly how to arrange the results to look like a table. I read about DataFrames and arrays using panda but this is what I got so far: 

 

 

import arcpy
import numpy as np
import pandas as pd

domains = arcpy.da.ListDomains("E:\ArcProMaps\MySDEConnection.sde")

for domain in domains:
    data1 = ('Domain name: {0}'.format(domain.name))
    s1 = pd.Series(data1)
    print(s1)
    if domain.domainType == 'CodedValue':
        coded_values = domain.codedValues
        for val, desc in coded_values.items():
            data2 = (data1, '{0} : {1}'.format(val, desc))
            s2 = pd.Series(data2)
            print(s2)
    elif domain.domainType == 'Range':
        print(data2,'Min: {0}'.format(domain.range[0]))
        print(data2,'Max: {0}'.format(domain.range[1]))

 

 

 

But I get this instead:

0    Domain name: piPipeShape
dtype: object
0    Domain name: piPipeShape
1         Circular : Circular
dtype: object
0    Domain name: piPipeShape
1       Horseshoe : Horseshoe
dtype: object
0    Domain name: piPipeShape
1             Oblong : Oblong
dtype: object
0     Domain name: piPipeShape
1    Rectangular : Rectangular
dtype: object
0     Domain name: piPipeShape
1    Trapezoidal : Trapezoidal
dtype: object
0    Domain name: piPipeShape
1     Triangular : Triangular
dtype: object
0    Domain name: piPipeShape
1               Other : Other
dtype: object
0    Domain name: piPipeShape
1           Unknown : Unknown

But what I want is something like this and/or easier to read and be able to export to Excel or perhaps a .csv file. 

Domain NamepiPipeShape 
1 (Enumerate them)Circular (Code)Circular (Description)
2Horseshoe (Code)Horseshoe (Description)
3Oblong (Code)Oblong (Description)
4Rectangular (Code)Rectangular (Description)
5Trapezoidal (Code)Trapezoidal (Description)
6Triangular (Code)Triangular (Description)
Domain NameSSM_YesNoUnknown  
1Yes (Code)Yes  (Description)
2No (Code)No (Description)
3Unknown (Code)Unknown (Description)

etc, etc, etc.....

Also, not sure how to put range codes into a series/array/data frame. 

I've read more community posts and documentation than I can count. 

Please lend me a helping hand or at least guide me to the right direction. 

Thank you. 

Jen Zumbado-Hannibal, GISP
GIS Coordinator
City of Forest Grove
Forest Grove, OR 97116

0 Kudos
2 Solutions

Accepted Solutions
JohannesLindner
MVP Frequent Contributor
# instead of a DataFrame, define your data as a simple twodimensional list
rows = []
column_names = ["DomainName", "DomainType", "Index", "Code", "Description", "Min", "Max"]

# fill the list
for domain in domains:
    if domain.domainType == "Range":
        row = [domain.name, domain.domainType, 0, None, None, domain.range[0], domain.range[1]]
        rows.append(row)
    else:
        for i, (k, v) in enumerate(domain.codedValues.items()):
            row = [domain.name, domain.domainType, i, k, v, None, None]
            rows.append(row)

# convert to DataFrame
dataframe = pd.DataFrame(rows, columns=column_names)

# export
dataframe.to_csv("N:/folder/domains.csv", index=False)
dataframe.to_excel("N:/folder/domains.xlsx", index=False)

 

JohannesLindner_0-1673606047177.png

 


Have a great day!
Johannes

View solution in original post

Clubdebambos
Occasional Contributor III

 

import arcpy
import csv

gdb = r"path\to\geodatabase.sde"

csv_filepath = r"path\to\export.csv"

domains = arcpy.da.ListDomains(gdb)

with open(csv_filepath, 'w', newline="") as csv_file:
    writer = csv.writer(csv_file)
    ## write the header
    writer.writerow(["DOMAIN_NAME", "DOMAIN_TYPE", "CODE/MIN", "DESCRIPTION/MAX"])

    for domain in domains:
        print(domain.name)
        if domain.domainType == 'CodedValue':
            coded_values = domain.codedValues
            for val, desc in coded_values.items():
                print('\t{0} : {1}'.format(val, desc))
                writer.writerow((domain.name,"Coded", val, desc))
        else:
            range_min = domain.range[0]
            range_max = domain.range[1]
            print("\t", range_min, range_max)
            writer.writerow((domain.name,"Range", range_min, range_max))

 

~ Mapping my way to retirement

View solution in original post

3 Replies
JohannesLindner
MVP Frequent Contributor
# instead of a DataFrame, define your data as a simple twodimensional list
rows = []
column_names = ["DomainName", "DomainType", "Index", "Code", "Description", "Min", "Max"]

# fill the list
for domain in domains:
    if domain.domainType == "Range":
        row = [domain.name, domain.domainType, 0, None, None, domain.range[0], domain.range[1]]
        rows.append(row)
    else:
        for i, (k, v) in enumerate(domain.codedValues.items()):
            row = [domain.name, domain.domainType, i, k, v, None, None]
            rows.append(row)

# convert to DataFrame
dataframe = pd.DataFrame(rows, columns=column_names)

# export
dataframe.to_csv("N:/folder/domains.csv", index=False)
dataframe.to_excel("N:/folder/domains.xlsx", index=False)

 

JohannesLindner_0-1673606047177.png

 


Have a great day!
Johannes
Clubdebambos
Occasional Contributor III

 

import arcpy
import csv

gdb = r"path\to\geodatabase.sde"

csv_filepath = r"path\to\export.csv"

domains = arcpy.da.ListDomains(gdb)

with open(csv_filepath, 'w', newline="") as csv_file:
    writer = csv.writer(csv_file)
    ## write the header
    writer.writerow(["DOMAIN_NAME", "DOMAIN_TYPE", "CODE/MIN", "DESCRIPTION/MAX"])

    for domain in domains:
        print(domain.name)
        if domain.domainType == 'CodedValue':
            coded_values = domain.codedValues
            for val, desc in coded_values.items():
                print('\t{0} : {1}'.format(val, desc))
                writer.writerow((domain.name,"Coded", val, desc))
        else:
            range_min = domain.range[0]
            range_max = domain.range[1]
            print("\t", range_min, range_max)
            writer.writerow((domain.name,"Range", range_min, range_max))

 

~ Mapping my way to retirement
Jen_Zumbado-Hannibal
Occasional Contributor

Thank you @JohannesLindner and @Clubdebambos  for your help. It worked perfectly! 

I just have to remember to import csv module too 😉

Jen Zumbado-Hannibal, GISP
GIS Coordinator
City of Forest Grove
Forest Grove, OR 97116