ESRI should implement a feature that allows the user to change the Split Policy for all of the domains in a feature class or geodatabase at the same time. Most often when splitting a shape feature, the original information from all or most fields is desired to be retained in both of the new records. Changing the split domain for all domains to "Duplicate" from "Default" one by one is cumbersome and time consuming. An ArcPy solution is shown in another thread, however this would be a useful feature to implement in the GUI to streamline workflows for many users.
Thanks for the Idea @EricPetersen . I can see how this would be a useful feature in the UI now that we've enabled multiselect in the domains view.
For those finding themselves here while this idea develops, the following python command can be used to achieve this.
import arcpy
gdb = <path to your geodatabase>
split = "DEFAULT" # (DEFAULT/DUPLICATE/GEOMETRY_RATIO* - Range Domains Only ))
domains = arcpy.da.ListDomains(gdb)
for domain in domains:
arcpy.management.AlterDomain(
in_workspace=gdb,
domain_name=domain.name,
split_policy=split,
)
For more information on the Alter Domain GP tool check out the documentation below.
Alter Domain Geoprocessing Tool
Good Day @SSWoodward ,
I presume that I still need to remove any locks on the EGDB before running the script?
Thank you
In general, schema changes do require an exclusive lock.
Trying to change the split policy of a domain while another user has the domains view open, for example, will raise
ERROR 160284: Cannot acquire a schema lock because of an existing lock.
@SSWoodward I employed your code... worked like a champ...
import arcpy
import os
from datetime import datetime
# Parameters
server = r"udog"
database = "gis_prod"
username = "sde"
password = "MPblahblahblah" Add the password after creating the script
log_file_path = r"c:\temp\SplitChangePolicy5_Log.txt"
split_policy = "DUPLICATE" # Desired split policy
# Function to write logs
def write_log(message):
try:
with open(log_file_path, "a") as log_file:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_file.write(f"{timestamp} - {message}\n")
print(message)
except Exception as e:
print(f"Error writing to log file: {e}")
# Initialize the log file
def initialize_log():
try:
if os.path.exists(log_file_path):
os.remove(log_file_path)
write_log("Log file initialized.")
except Exception as e:
print(f"Error initializing log file: {e}")
exit(1)
# Function to create a workspace connection
def create_workspace():
try:
connection_file = os.path.join(r"c:\temp", "gis_prod_util_connection5.sde")
if os.path.exists(connection_file):
os.remove(connection_file)
arcpy.CreateDatabaseConnection_management(
out_folder_path=r"c:\temp",
out_name="gis_prod_util_connection5.sde",
database_platform="SQL_SERVER",
instance=server,
account_authentication="DATABASE_AUTH",
username=username,
password=password,
save_user_pass="SAVE_USERNAME",
database=database
)
write_log(f"Workspace connection created: {connection_file}")
return connection_file
except Exception as e:
error_message = f"Error creating workspace connection: {e}"
write_log(error_message)
write_log(arcpy.GetMessages(2))
exit(1)
# Function to update domains and check compatibility
def update_domains_and_check_geometry(gdb):
try:
domains = arcpy.da.ListDomains(gdb)
if not domains:
write_log("No domains found in the geodatabase.")
return
total_domains = len(domains)
write_log(f"Total domains in geodatabase: {total_domains}")
for domain in domains:
try:
# Log domain details
write_log(f"Processing domain: {domain.name}")
# Get feature classes using the domain
associated_classes = get_feature_classes_using_domain(gdb, domain.name)
for fc in associated_classes:
# Check geometry type compatibility
desc = arcpy.Describe(fc)
geometry_type = desc.shapeType
if domain.split_policy == "GEOMETRY_RATIO" and geometry_type == "Point":
write_log(
f"Warning: Domain '{domain.name}' with GEOMETRY_RATIO is applied to point feature class '{fc}', which is not supported.")
else:
write_log(
f"Domain '{domain.name}' is compatible with feature class '{fc}' of type '{geometry_type}'.")
# Update the split policy for the domain
arcpy.management.AlterDomain(
in_workspace=gdb,
domain_name=domain.name,
split_policy=split_policy
)
write_log(f"Domain '{domain.name}' updated with split policy '{split_policy}'.")
except Exception as e:
write_log(f"Error updating domain '{domain.name}': {e}")
write_log(arcpy.GetMessages(2))
except Exception as e:
write_log(f"Error listing or updating domains: {e}")
write_log(arcpy.GetMessages(2))
# Function to get feature classes using a specific domain
def get_feature_classes_using_domain(gdb, domain_name):
feature_classes = []
arcpy.env.workspace = gdb
for fc in arcpy.ListFeatureClasses():
fields = arcpy.ListFields(fc)
for field in fields:
if field.domain == domain_name:
feature_classes.append(fc)
break
return feature_classes
# Main script execution
def main():
start_time = datetime.now()
initialize_log()
write_log(f"Script started at {start_time.strftime('%Y-%m-%d %H:%M:%S')}.")
try:
# Create workspace connection
workspace = create_workspace()
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
# Update domains and check compatibility with geometry types
update_domains_and_check_geometry(workspace)
end_time = datetime.now()
elapsed_time = (end_time - start_time).total_seconds()
hours, remainder = divmod(elapsed_time, 3600)
minutes, seconds = divmod(remainder, 60)
write_log(f"Script completed successfully at {end_time.strftime('%Y-%m-%d %H:%M:%S')}.")
write_log(f"Elapsed time: {int(hours)} hours, {int(minutes)} minutes, {seconds:.2f} seconds.")
print(f"Script completed successfully in {int(hours)} hours, {int(minutes)} minutes, {seconds:.2f} seconds.")
except Exception as e:
write_log(f"An error occurred: {e}")
write_log(arcpy.GetMessages(2))
if __name__ == "__main__":
main()
@SSWoodward I employed your code snippet and it worked like a champ...
import arcpy
import os
from datetime import datetime
# Parameters
server = r"un-az"
database = "gis_prod"
username = "sde"
password = "MjunkjunkJunk" # Add the password after creating the script
log_file_path = r"c:\temp\SplitChangePolicy5_Log.txt"
split_policy = "DUPLICATE" # Desired split policy
# Function to write logs
def write_log(message):
try:
with open(log_file_path, "a") as log_file:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_file.write(f"{timestamp} - {message}\n")
print(message)
except Exception as e:
print(f"Error writing to log file: {e}")
# Initialize the log file
def initialize_log():
try:
if os.path.exists(log_file_path):
os.remove(log_file_path)
write_log("Log file initialized.")
except Exception as e:
print(f"Error initializing log file: {e}")
exit(1)
# Function to create a workspace connection
def create_workspace():
try:
connection_file = os.path.join(r"c:\temp", "gis_prod_util_connection5.sde")
if os.path.exists(connection_file):
os.remove(connection_file)
arcpy.CreateDatabaseConnection_management(
out_folder_path=r"c:\temp",
out_name="gis_prod_util_connection5.sde",
database_platform="SQL_SERVER",
instance=server,
account_authentication="DATABASE_AUTH",
username=username,
password=password,
save_user_pass="SAVE_USERNAME",
database=database
)
write_log(f"Workspace connection created: {connection_file}")
return connection_file
except Exception as e:
error_message = f"Error creating workspace connection: {e}"
write_log(error_message)
write_log(arcpy.GetMessages(2))
exit(1)
# Function to update domains and check compatibility
def update_domains_and_check_geometry(gdb):
try:
domains = arcpy.da.ListDomains(gdb)
if not domains:
write_log("No domains found in the geodatabase.")
return
total_domains = len(domains)
write_log(f"Total domains in geodatabase: {total_domains}")
for domain in domains:
try:
# Log domain details
write_log(f"Processing domain: {domain.name}")
# Get feature classes using the domain
associated_classes = get_feature_classes_using_domain(gdb, domain.name)
for fc in associated_classes:
# Check geometry type compatibility
desc = arcpy.Describe(fc)
geometry_type = desc.shapeType
if domain.split_policy == "GEOMETRY_RATIO" and geometry_type == "Point":
write_log(
f"Warning: Domain '{domain.name}' with GEOMETRY_RATIO is applied to point feature class '{fc}', which is not supported.")
else:
write_log(
f"Domain '{domain.name}' is compatible with feature class '{fc}' of type '{geometry_type}'.")
# Update the split policy for the domain
arcpy.management.AlterDomain(
in_workspace=gdb,
domain_name=domain.name,
split_policy=split_policy
)
write_log(f"Domain '{domain.name}' updated with split policy '{split_policy}'.")
except Exception as e:
write_log(f"Error updating domain '{domain.name}': {e}")
write_log(arcpy.GetMessages(2))
except Exception as e:
write_log(f"Error listing or updating domains: {e}")
write_log(arcpy.GetMessages(2))
# Function to get feature classes using a specific domain
def get_feature_classes_using_domain(gdb, domain_name):
feature_classes = []
arcpy.env.workspace = gdb
for fc in arcpy.ListFeatureClasses():
fields = arcpy.ListFields(fc)
for field in fields:
if field.domain == domain_name:
feature_classes.append(fc)
break
return feature_classes
# Main script execution
def main():
start_time = datetime.now()
initialize_log()
write_log(f"Script started at {start_time.strftime('%Y-%m-%d %H:%M:%S')}.")
try:
# Create workspace connection
workspace = create_workspace()
arcpy.env.workspace = workspace
arcpy.env.overwriteOutput = True
# Update domains and check compatibility with geometry types
update_domains_and_check_geometry(workspace)
end_time = datetime.now()
elapsed_time = (end_time - start_time).total_seconds()
hours, remainder = divmod(elapsed_time, 3600)
minutes, seconds = divmod(remainder, 60)
write_log(f"Script completed successfully at {end_time.strftime('%Y-%m-%d %H:%M:%S')}.")
write_log(f"Elapsed time: {int(hours)} hours, {int(minutes)} minutes, {seconds:.2f} seconds.")
print(f"Script completed successfully in {int(hours)} hours, {int(minutes)} minutes, {seconds:.2f} seconds.")
except Exception as e:
write_log(f"An error occurred: {e}")
write_log(arcpy.GetMessages(2))
if __name__ == "__main__":
main()
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.