FieldMap and FieldMappings arrgh....

02-27-2018 10:53 AM
MVP Esteemed Contributor

I'm trying to get FieldMappings—Help | ArcGIS Desktop  to work.  The need is to append records from one table to records of a different table with the NO_TEST option as the two don't have the same schemas.  I've tried with a table to table append, and also with a feature class to feature class append.  In both cases I can get the records from one table to append to the target table, and feature geometry to append to the target feature class.  But....  None of the attribute values come over in either case. This has to be one of the most complex processes I've ever seen, and I cannot for the life of me see where the issue is.  Below is the python script I'm using to do it; pretty much right out of the help page.  If anyone has had this work for them, perhaps your second set of eyes is what I need....

import arcpy

in_file1 = r'C:\Replicas\Replicas.gdb\MasterStreetNameFC'
#output_file = r'C:\Replicas\Replicas.gdb\CoordOverlapErrors'
output_file = r'C:\Replicas\Replicas.gdb\Points'

fm_streetname = arcpy.FieldMap()
fm_type = arcpy.FieldMap()
fm_housedir = arcpy.FieldMap()
fm_begrange = arcpy.FieldMap()
fm_endrange = arcpy.FieldMap()
fm_begcoord = arcpy.FieldMap()
fm_endcoord = arcpy.FieldMap()
fm_streetdir = arcpy.FieldMap()
fm_cityjurs = arcpy.FieldMap()
fm_zipcode = arcpy.FieldMap()
fm_oid = arcpy.FieldMap()

fms = arcpy.FieldMappings()

##s_name = 'StreetName'
##s_type = 'Type'
##s_housedir = 'HouseDir'
##s_begrange = 'BegRange'
##s_endrange = 'EndRange'
##s_begcoord = 'BegCoord'
##s_endcoord = 'EndCoord'
##s_streetdir = 'StreetDir'
##s_cityjurs = 'CityJurs'
##s_zipcode = 'ZipCode'
##s_oid = 'OBJECTID'
## These variables are commented out
## as I used the actual field names below
## thinking maybe the variables were the problem...

fm_type.addInputField(in_file1, 'Type')
fm_housedir.addInputField(in_file1, 'HouseDIr')
fm_begrange.addInputField(in_file1, 'BegRange')
fm_endrange.addInputField(in_file1, 'EndRange')
fm_begcoord.addInputField(in_file1, 'BegCoord')
fm_endcoord.addInputField(in_file1, 'EndCoord')
fm_streetdir.addInputField(in_file1, 'StreetDir')
fm_cityjurs.addInputField(in_file1, 'CityJurs')
fm_zipcode.addInputField(in_file1, 'ZipCode')
fm_oid.addInputField(in_file1, 'OBJECTID')

StreetName1 = fm_streetname.outputField
Type1 = fm_type.outputField
HouseDir1 = fm_housedir.outputField
BegRange1 = fm_begrange.outputField
EndRange1 = fm_endrange.outputField
BegCoord1 = fm_begcoord.outputField
EndCoord1 = fm_endcoord.outputField
StreetDir1 = fm_streetdir.outputField
CityJurs1 = fm_cityjurs.outputField
Zip1  = fm_zipcode.outputField
OID1 = fm_oid.outputField
StreetName2 = fm_streetname.outputField
Type2 = fm_type.outputField
HouseDir2 = fm_housedir.outputField
BegRange2 = fm_begrange.outputField
EndRange2 =  fm_endrange.outputField
BegCoord2 = fm_begcoord.outputField
EndCoord2 =  fm_endcoord.outputField
StreetDir2 = fm_streetdir.outputField
CityJurs2 = fm_cityjurs.outputField
Zip2 = fm_zipcode.outputField
OID2 = fm_oid.outputField


That should just about do it....
0 Kudos
12 Replies
Occasional Contributor

I'm not sure if it's strictly necessary or if it's possible to achieve the equivalent result without it, but when creating the FieldMappings object in the past I've called the addTable method immediately after creation, passing in the input dataset(s).

0 Kudos
MVP Esteemed Contributor

Thanks for your reply, but I don't quite follow what you are suggesting.  FWIW, it appears I missed this section provided in the help:

# Set the output field properties for both FieldMap objects 
type_name = fm_type.outputField = 'Veg_Type' 
fm_type.outputField = type_name 
diam_name = fm_diam.outputField = 'Veg_Diam' 
fm_diam.outputField = diam_name

I'm hoping that's all it is....

That should just about do it....
0 Kudos
Occasional Contributor

If that doesn't work, try adding this second line after your line 20:

fms = arcpy.FieldMappings()
0 Kudos
Regular Contributor

Hey Joe,

If you don't want to hard code your field mappings, here's a way to store the info in a table that then you can then use as a parameter in a custom tool. It will build the field mappings object for you and then append the data as specified in your table. 


MVP Esteemed Contributor

Hey mbabinski1988‌ ; that looks promising for my application.  Thanks for the tip!

That should just about do it....
0 Kudos
New Contributor III

I've never been a big fan of the fieldmapping quagmire, probably because I'm much too lazy to read the docs.  If I were appending to a table NO_TEST style, I'd read the data from the origin table w/ a search cursor and then simply use an insert cursor on the append table and keep my fields straight. 

Occasional Contributor

I usually stick with cursors as well but I've found using off-the-shelf tools and field mappings typically provide better performance than cursors... So if it's something I'm going to be running regularly and performance matters, I bite the bullet and get into mappings.

MVP Esteemed Contributor

Kev- couldn't agree with you more: field mapping is indeed a quagmire.  In this particular case though a cursor is probably going be sluggish at best. 

That should just about do it....
0 Kudos
New Contributor III

My code usually runs off-hours, so I'll take a performance hit for the sake of more simple code.  Has anyone bench marked the difference?  I thought da.xCursors were super fast!

0 Kudos