1

I am transforming one feature class into another (currently empty) feature class.

The input feature class and output feature class share the same fields, but the output feature class has some additional fields. I'm aware I can do this using a Data Acess module InsertCursor, but I'm trying to learn how to use the FieldMappings module and got stuck here.

 staging = 'C:/Path/To/Input.gdb'
 gdb = 'C:/Path/To/Output.gdb'
 input_fc = os.path.join(staging, 'Hazard')
 output_fc = os.path.join(gdb, 'Hazard')


# Get a list of common fields
common_fields = [f for f in input_fields if f.name in [g.name for g in output_fields] and not f.required]
# Get a list of fields found in the output, but not in the input
uncommon_fields = [f for f in output_fields if not f.name in [g.name for g in input_fields] and not f.required]
# Get a list of fields found in the input, but not in the output
unmapped_fields = [f for f in input_fields if f.name not in [g.name for g in output_fields] and not f.required]
print [f.name for f in common_fields]
print '*' * 20
print [f.name for f in uncommon_fields]
print '*' * 20
print [f.name for f in unmapped_fields]

This returns

[u'hazard_type', u'inspection_staff', u'comments', u'inspection_date', u'pp_survey_cycle', u'pp_timestamp', u'record_uid', u'record_timestamp', u'flagged', u'reason_flagged', u'marked_for_deletion', u'data_quality_assured', u'data_qa_staff', u'data_qa_comments', u'data_qa_timestamp', u'gdb_timestamp']
********************
[u'pp_azu', u'pp_city', u'pp_state', u'pp_zip', u'pp_survey_group']
********************
[]

What I want to happen is for fields in common_fields to get mapped over to output_fc and fields in uncommon_fields to remain Null.

Here's the code I'm using, which runs without error but doesn't append anything (grr ESRI...). Do I have to specifically remove fields from the FieldMappings object? How do I do that?

# Specify the mappings using a dictionary. We're just mapping fields that have the same name to one another here.
custom_mappings = {}

for f in input_fields:
    if not f.required:
        custom_mappings[f] = next((g for g in output_fields if g.name == f.name), None)

# Create field mapping object
fms = arcpy.FieldMappings()

# Specify the field map for each field and add it to the FieldMappings object
for field in input_fields:
    if not field.required:
        fm = arcpy.FieldMap()
        fm.addInputField(input_fc, field.name)
        fm.outputField = custom_mappings[field]
        fms.addFieldMap(fm)

# Append to the output_fc using the field mappings
arcpy.Append_management(input_fc, output_fc, 'NO_TEST', fms)
2
  • Append using NO_TEST will automatically match fields with the same name. So why use field mapping? Commented Dec 28, 2016 at 22:09
  • I'm using this workflow for more complex mappings for other feature classes, and I'm also just trying to learn how to use the FieldMappings module more generally.
    – KJYDavis
    Commented Dec 28, 2016 at 22:21

2 Answers 2

1

This worked for me. Based mostly on your code

input_fc = "Input FC"
output_fc = "Output FC"

input_fields = arcpy.ListFields(input_fc)
output_fields = arcpy.ListFields(output_fc)


custom_mappings = {}
for f in input_fields:
    if not f.required:
        custom_mappings[f] = next((g for g in output_fields if g.name == f.name), None)

#Check Fields:
#You don't really need these lists, only the custom_mappings dictionary
common_fields = [f for f in input_fields if f.name in [g.name for g in output_fields] and not f.required]
uncommon_fields = [f for f in output_fields if not f.name in [g.name for g in input_fields] and not f.required]
unmapped_fields = [f for f in input_fields if f.name not in [g.name for g in output_fields] and not f.required]
for l in [common_fields, uncommon_fields, unmapped_fields]:
    for f in l: print f.name
    print '*' * 20
for k in custom_mappings.keys(): print "{} : {}".format( k.name, custom_mappings[k].name)
print '*' * 20

#Make Field Mappings
fms = arcpy.FieldMappings()
for k in custom_mappings.keys():
    fm = arcpy.FieldMap()
    fm.addInputField(input_fc, k.name)
    fm.outputField = custom_mappings[k]
    fms.addFieldMap(fm)

#Check Field Mappings
print fms.exportToString()

arcpy.Append_management(input_fc, output_fc, 'NO_TEST', fms)  
0

In place of this line:
fm.outputField = custom_mappings[field]

replace with these 3 lines:
type_name = fm.outputField
type_name.name = custom_mappings[field].name
fm.outputField = type_name

1
  • This doesn't work. Custom_mappings contains Field objects, not names, so custom_mappings[field] can't be assigned to type_name.name. Second, fm_type is not defined in my script, so I don't know what it's supposed to be doing. Third, fm.outputField is writable, so assigning it directly is fine. This script works for other feature classes where all the output fields are mapped, so I don't think that line is the offending one.
    – KJYDavis
    Commented Dec 28, 2016 at 22:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.