Update Split Policy or Merge Policy for a Domain in an ArcGIS Online Hosted Feature Service with the ArcGIS API for Python

You may come across a couple of scenarios…
1. You have published a hosted feature service to ArcGIS Online (AGOL) with domains and the dataset has matured with edits. You do not want unshare, export, download, and republish to overwrite the feature service but you need to update the split/merge policy to make edits easier and to comply with your data rules.
2. You have created/are creating a hosted feature service in AGOL and you wish to include split/merge policies for a domain but there is no apparent option for these available. I have added as an idea in Esri Communities.

For a Coded Value Domain the Split Policy can be either Default or Duplicate, and the Merge Policy can only be Default.

For a Range Domain, the Split Policy can be Default, Duplicate, or Geometery Ratio, and the Merge Policy can be Default, Area Weighted, or Sum Values.

We are going to show how you can use the ArcGIS API for Python to update the policies. You can create a Coded Value Domain from the Fields view in the Data tab by selecting a field of choice.

Add displayed values and the stored values. Below, we are using a long (numeric) coded value domains. Notice there are no options to set Split Policy! (Merge Policy will always be Default for a Coded Value Domain)

Now, let’s check the domain for the field using the ArcGIS API for Python to get the information for a specific field as JSON and print to screen.

from arcgis.gis import GIS

## connect to AGOL
agol = GIS("home")

## access the feature service item
item = agol.content.get("FS_ITEM_ID")

## access feature layer that contains the field with the domain
## the below is using an index to access the first layer in the feature service
fl = item.layers[0]

## get the JSON for the field of interest
## CodedDomainExample is the name of the field of interest for this workflow
field = [field for field in fl.properties.fields if field["name"] == "CodedDomainExample"][0]

## and print to screen
print(field)

And the output printed to screen.

{
  "name": "CodedDomainExample",
  "type": "esriFieldTypeInteger",
  "alias": "CodedDomainExample",
  "sqlType": "sqlTypeOther",
  "nullable": true,
  "editable": true,
  "domain": {
    "type": "codedValue",
    "name": "flname_CodedDomainExample",
    "codedValues": [
      {
        "name": "Description 1",
        "code": 1
      },
      {
        "name": "Description 2",
        "code": 2
      },
      {
        "name": "Description 3",
        "code": 3
      }
    ]
  },
  "defaultValue": 1
}

Still no Split (or Merge) Policy to be seen! Lets open the feature service in ArcGIS Pro and check the Domain information. Add the feature service/feature layer to a Map, right-click on the layer in the Contents Pane > Data Design > Domains. We can see that both the Split and Merge Policies are set to Default and these are read-only in ArcGIS Pro so they cannot be altered for the feature service.

But we want to update our Split Policy to Duplicate! Copy the JSON printed to screen with the field information and create a dictionary as shown below and add in the Split and Merge policies. Although the Merge Policy can only be Default, let’s be explicit so it shows up in future field information extractions for our field in the feature layer.

from arcgis.gis import GIS

## connect to AGOL
agol = GIS("home")

## access the feature service item
item = agol.content.get("FS_ITEM_ID")

## access feature layer that contains the field with the domain
## the below is using an index to access the first layer in the feature service
fl = item.layers[0]

## get the JSON for the field of interest
## CodedDomainExample is the name of the field of interest for this workflow
field = [field for field in fl.properties.fields if field["name"] == "CodedDomainExample"][0]

## copy and paste the JSON for the field, update true to True (if there was
## false, update to False. Add in the "mergePolicy" and "splitPolicy"
## if you wanted to set "splitPolicy" back to Default use "esriSPTDefault"
field_update = {
  "name": "CodedDomainExample",
  "type": "esriFieldTypeInteger",
  "alias": "CodedDomainExample",
  "sqlType": "sqlTypeOther",
  "nullable": True,
  "editable": True,
  "domain": {
    "type": "codedValue",
    "name": "flname_CodedDomainExample",
    "codedValues": [
      {
        "name": "Description 1",
        "code": 1
      },
      {
        "name": "Description 2",
        "code": 2
      },
      {
        "name": "Description 3",
        "code": 3
      }
    ],
    "mergePolicy": "esriMPTDefaultValue",
    "splitPolicy": "esriSPTDuplicate"
  },
  "defaultValue": 1
}

## update the service definition
print(fl.manager.update_definition({"fields" : [field_update]}))

Re-run the first script that prints the JSON to screen and see that the update has taken affect.

{
  "name": "CodedDomainExample",
  "type": "esriFieldTypeInteger",
  "alias": "CodedDomainExample",
  "sqlType": "sqlTypeOther",
  "nullable": true,
  "editable": true,
  "domain": {
    "type": "codedValue",
    "name": "flname_CodedDomainExample",
    "mergePolicy": "esriMPTDefaultValue",
    "splitPolicy": "esriSPTDuplicate",
    "codedValues": [
      {
        "name": "Description 1",
        "code": 1
      },
      {
        "name": "Description 2",
        "code": 2
      },
      {
        "name": "Description 3",
        "code": 3
      }
    ]
  },
  "defaultValue": 1
}

And while we’re at it lets check out ArcGIS Pro. The Split Policy is now set to Duplicate. You might need to remove the feature service from your Map first and re-add to see this take affect.

That’s Coded Value Domains boxed off, let’s take a look at Split and Merge Policies for a Range Domain. Very similar workflow. We have created a Range Domain.

Re-use the first code snippet to print the field information JSON to screen. Note, no Split or Merge Policy.

{
  "name": "RangeDomainExample",
  "type": "esriFieldTypeInteger",
  "alias": "RangeDomainExample",
  "sqlType": "sqlTypeOther",
  "nullable": true,
  "editable": true,
  "domain": {
    "type": "range",
    "name": "flname_RangeDomainExample",
    "range": [
      1,
      100
    ]
  },
  "defaultValue": 1
}

Copy and paste the JSON similar to what we performed earlier and add in the Split and Merge Policies similar to below.

from arcgis.gis import GIS

## connect to AGOL
agol = GIS("home")

## access the feature service item
item = agol.content.get("FS_ITEM_ID")

## access feature layer that contains the field with the domain
## the below is using an index to access the first layer in the feature service
fl = item.layers[0]

## get the JSON for the field of interest
## RangeDomainExample is the name of the field of interest for this workflow
field = [field for field in fl.properties.fields if field["name"] == "RangeDomainExample"][0]

## copy and paste the JSON for the field, update true to True (if there was
## false, update to False. Add in the "mergePolicy" and "splitPolicy"
## "splitPolicy" can be "esriSPTDefault", "esriSPTDuolicate", "esriSPTGeometryRatio"
## "mergePolicy" can be "esriMPTDefault", ""esriMPTSumValues"", "esriMPTAreaWeighted"
field_update = {
  "name": "RangeDomainExample",
  "type": "esriFieldTypeInteger",
  "alias": "RangeDomainExample",
  "sqlType": "sqlTypeOther",
  "nullable": True,
  "editable": True,
  "domain": {
    "type": "range",
    "name": "flname_RangeDomainExample",
    "range": [
      1,
      100
    ],
    "mergePolicy": "esriMPTSumValues",
    "splitPolicy": "esriSPTGeometryRatio"
  },
  "defaultValue": 1
}

## update the service definition
print(fl.manager.update_definition({"fields" : [field_update]}))

You can re-print the field information JSON or check to ArcGIS Pro to see the update has take affect.

We have show that we can use the ArcGIS API for Python to update a Split or Merge Policy for a Coded Value and Range Domain that is not easily accessible when initially creating the Domain in the Fields view in the Data tab for a feature layer.

Leave a Comment

Your email address will not be published. Required fields are marked *