Hi,
I ran into a bit of an issue regarding domain values from a list of domains in a database. I don't know if there are limitations regarding a .fgdb vs .sde databases, but I wanted to see if there was a way to get either the range values or the coded values from an .sde database. I wrote a script to access it, which seems to work partially, but I am not sure why it isn't working on an .sde database. Any help on this would be appreciated.
import arcpy, os, datetime
from arcpy import ListFields, CreateFileGDB_management as CreateGDB, Point
from arcpy.da import Editor as Editing, SearchCursor as Searching, InsertCursor as Inserting, UpdateCursor as Updating, Walk, ListDomains as GetDomains
from arcpy.management import CopyFeatures as ReplicateFeature, CreateFeatureDataset as MakeDataset, CreateRelationshipClass as MakeRelation, CreateTable, AddField
from arcpy.conversion import ExportTable as ReplicateTable
from datetime import datetime, timedelta
from os import chdir as SetDirectory, mkdir as CreateDirectory
from os.path import basename as RootName, join as Combine, exists as Existing, dirname as ParentDirectory, isfile
# Get coded domains and descriptions for populating specific fields
def CodedDomains(Database, SpecifiedDomain):
DomainValues = None
if '.gdb' in Database:
for Domain in GetDomains(Database):
if Domain.name == SpecifiedDomain: DomainValues = Domain.codedValues
return DomainValues
CodedValues = CodedDomains(Database, DomainName)
for Code, Value in CodedValues.items(): print (f'"{Code}": "{Value}",')
Solved! Go to Solution.
I can't test on an SDE, but this code has worked before:
import arcpy, pandas
domains = arcpy.da.ListDomains("C:/bla/database.sde")
# create an empty to-dimensional list to store the domain data
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 = pandas.DataFrame(rows, columns=column_names)
# export
dataframe.to_csv("C:/bla/domains.csv", index=False)
dataframe.to_excel("C:/bla/domains.xlsx", index=False)
Oh god, please don't rename these imports. You, your successor, and people trying to help you are going to have a really bad time trying to figure out where eg "ReplicateFeature" is coming from and what it does. But we do know where to look up the docs for "arcpy.management.CopyFeatures". Just import arcpy and leave it at that.
In line 15, you're checking for ".gdb" in the database path, and only if it's there do you actually get the domain values. If you input a .sde, the if block will be skipped and the function will return None.
I have changed it from .gdb to .sde and it still returns a none value.
I can't test on an SDE, but this code has worked before:
import arcpy, pandas
domains = arcpy.da.ListDomains("C:/bla/database.sde")
# create an empty to-dimensional list to store the domain data
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 = pandas.DataFrame(rows, columns=column_names)
# export
dataframe.to_csv("C:/bla/domains.csv", index=False)
dataframe.to_excel("C:/bla/domains.xlsx", index=False)