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 Name | piPipeShape | |
1 (Enumerate them) | Circular (Code) | Circular (Description) |
2 | Horseshoe (Code) | Horseshoe (Description) |
3 | Oblong (Code) | Oblong (Description) |
4 | Rectangular (Code) | Rectangular (Description) |
5 | Trapezoidal (Code) | Trapezoidal (Description) |
6 | Triangular (Code) | Triangular (Description) |
Domain Name | SSM_YesNoUnknown | |
1 | Yes (Code) | Yes (Description) |
2 | No (Code) | No (Description) |
3 | Unknown (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.
Solved! Go to Solution.
# 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)
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))
# 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)
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))
Thank you @JohannesLindner and @Clubdebambos for your help. It worked perfectly!
I just have to remember to import csv module too 😉