ArcGIS Pro Python Toolbox – Implementing FieldMapping Parameter to Map Fields in Two Tables

arcgis-proarcpyfield-mappingpython-toolbox

I am trying to create a tool within a Python Toolbox in ArcGIS Pro that will accept a table and a featureclass and allow a user to map the fields from the feature class to fields in the table. Ultimately, I want to use this mapping to match values in order to assign the 'Code' found in the table layer to the appropriate feature in the FC.

For example, here I'd like to map select fields between Table and FeatureClass (TBL:FC)
County:County
DistrictA:OtherDistrict
DistrictB:SomeDistrict

As you can see, the fields have different names, and are not in the same order across the two tables.

Table 1:

OID County DistrictA DistrictB Code
0 A 0 A 111
1 A xyz ABC 112
2 B 0 A 113
3 C XYZ abc 114

FeatureClass:

OID County SomeDistrict OtherDistrict
0 A A 0
1 C abc XYZ
2 B B 1
3 A ABC xyz

My approach has been to try and use the FieldMappings parameter and feed the two tables into it in order to allow a user to assign the mappings manually.
I have been trying to follow the approach of this post: https://community.esri.com/t5/python-questions/append-tool-and-field-mapping-help-examples/td-p/427282 , however this is not implemented within the Python Toolbox framework.
I also checked out Creating Field Mapping Parameter in Arcpy Script which put me on the right track. but I have run into the same issue as OP and cannot get a second input to be added.

Here is a snippet of my code as it stands:

def getParameterInfo(self):
        ""Define parameter definitions""
        param0 = arcpy.Parameter(
            displayName="Input Table",
            name="in_table",
            datatype="GPTableView",
            parameterType="Required",
            direction="Input",
        )

        param1 = arcpy.Parameter(
            displayName="Splits Feature Class",
            name="splits_layer",
            datatype="DEFeatureClass",
            parameterType="Required",
            direction="Input",
        )

        param2 = arcpy.Parameter(
            displayName="Field Mappings",
            name="in_fieldmappings",
            datatype="GPFieldMapping",
            parameterType="Required",
            direction="Input",
        )
        param2.value = str("Empty")

        params = [param0, param1, param2]
        return params

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""

        # retrieve the parameter values for both input tables
        Table1 = parameters[0].value
        Table2 = parameters[1].value

        # add table fields. Here, the tool populates the Fieldmap with the values from Table1 as 
        # as soon as a table is specified, but it overwrites with fields from Table2
        parameters[2].value.addTable(Table1)
        parameters[2].value.addTable(Table2)
        
        # Remove the empty field map created initially
        parameters[2].value.removeFieldMap(0)
        
        return

Best Answer

For that you only need ability to 're-order' fields in one of the tables, e.g. going from:

enter image description here

to:

enter image description here

You can do it inside tool validation:

  def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parameter
    has been changed."""
    for i in range(2):
      if self.params[i*3].altered and not self.params[i*3+2].altered:
        fromLYR=self.params[i*3].value
        newList=[f.name for f in arcpy.ListFields(fromLYR)]
        self.params[i*3+2].value = newList[:]
    return

These are the parameters I use:

enter image description here

Related Question