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'
#arcpy.MakeTableView_management(view1,in_file1)
#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_streetname.addInputField(in_file1,'StreetName')
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
fms.addFieldMap(fm_streetname)
fms.addFieldMap(fm_type)
fms.addFieldMap(fm_housedir)
fms.addFieldMap(fm_begrange)
fms.addFieldMap(fm_endrange)
fms.addFieldMap(fm_begcoord)
fms.addFieldMap(fm_endcoord)
fms.addFieldMap(fm_streetdir)
fms.addFieldMap(fm_cityjurs)
fms.addFieldMap(fm_zipcode)
fms.addFieldMap(fm_oid)
arcpy.Append_management(in_file1,output_file,'NO_TEST',fms)
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).
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
type_name.name = 'Veg_Type'
fm_type.outputField = type_name
diam_name = fm_diam.outputField
diam_name.name = 'Veg_Diam'
fm_diam.outputField = diam_name
I'm hoping that's all it is....
If that doesn't work, try adding this second line after your line 20:
fms = arcpy.FieldMappings()
fms.addTable(in_file1)
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.
https://community.esri.com/thread/182353-build-arcpy-field-mapping-object-from-table
Micah
Hey mbabinski1988 ; that looks promising for my application. Thanks for the tip!
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.
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.
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.
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!