I'm having trouble trying to understand how fieldmapping works in ArcPy (I'm kinda new to Python). In the below example, I want to take a shapefile and append it to a feature class. But I want to use the field map parameter so the fields from the shapefile go to the correct field names in the feature class. So I successfully built this out in ModelBuilder and exported the Python script (see below). But so much of it doesn't make sense, for example...what are all these different codes... -1, 0, #, true, false, etc. And there seems to be no documentation anywhere online on the meaning behind these codes.

Does anybody know what these mean?

Also, I read that I can use the fieldmapping() class as a parameter in this script.

How would I even incorporate that?

If you know a much easier way (via python) to field map then using the above methods, I'm open to those suggestions.

Edit: The code below is only a simple test that I created, so I can hopefully understand fieldmapping better. But in the long run I want to this to be able to handle a LOT of fields from many different shapefiles.

Source shapefile schema: Name, Code, Date

Target feature class schema: Description, Num, Date

# Import arcpy module
import arcpy

# Local variables:
New_Shapefile_shp = "C:\\New_Shapefile.shp"
New_Featureclass__2_ = New_Shapefile_shp
New_Featureclass = "C:\\Target.gdb\\New_Featureclass"

# Process: Append
arcpy.Append_management("C:\\New_Shapefile.shp", New_Featureclass, "NO_TEST", "DESCRIPTION \"DESCRIPTION\" true true false 150 Text 0 0 ,First,#,C:\\New_Shapefile.shp,Name,-1,-1;NUM \"NUM\" true true false 4 Long 0 0 ,First,#,C:\\New_Shapefile.shp,Code,-1,-1;DATE \"DATE\" true true false 8 Date 0 0 ,First,#,C:\\New_Shapefile.shp,Date,-1,-1", "")
  • 2
    Field mappings are difficult, I usually try to avoid them. You only have three fields? You could export the shape to a file gdb - alter field (to match the fc you want to append to) - append. Or use da.SearchCursor and da.InsertCursor to read the shape and add rows to the fc.
    – BERA
    Jul 10 '19 at 20:09
  • I only have 3 fields because this is just a test. The project I'm working on will have up to 5x the amount of fields and will have to iterate thru thousands of different shapefiles. In this test, I just wanted to keep it simple so I can understand what I'm looking at. I would agree with using your method, but I need something that can scale out.
    – user137548
    Jul 10 '19 at 20:17
  • The field names are always the same?
    – BERA
    Jul 10 '19 at 20:18
  • I would say yes on both ends (source, target). But I may create a separate script to handle different schemas from different shapefiles. I may also incorporate wildcards for the fieldnames, just in case match issues arise.
    – user137548
    Jul 10 '19 at 20:22

Another way of doing it using da.SearchCursor to read shapefile rows and insert them in the fc using da.InsertCursor:

import arcpy

shapefile = r'C:\folder\shapefile.shp'
fc = r'C:\data.gdb\featureclass'

#The position of the fields must match, Name=Description etc.
shapefields = ['Name','Code','Date']
fcfields = ['Description','Num','Date']

icur = arcpy.da.InsertCursor(fc, fcfields+['SHAPE@'])

with arcpy.da.SearchCursor(shapefile, shapefields+['SHAPE@']) as cursor:
    for row in cursor:

del icur
  • 3
    I think this is a far better alternative to working with field mappings.
    – PolyGeo
    Jul 10 '19 at 21:15
  • This is pretty awesome, yes this did work. Though would this also work when the one has more fields than the other?
    – user137548
    Jul 11 '19 at 20:21
  • Nice! Yes it should
    – BERA
    Jul 12 '19 at 6:26
  • 1
    Looking at the code in more detail, I was curious about the InsertCursor syntax. When I look it up online I see the following format InsertCursor (dataset, {spatial_reference}). In your script ` fcfields+['SHAPE@'] ` was used in the "spatial_reference" part of the parameter, how that is a "spatial_reference"? Hope this isn't a stupid question, I'm still kinda new to Python. Trying to understand it better. The way python operates seems really confusing sometimes.
    – user137548
    Jul 12 '19 at 13:27
  • @user137548 you are looking at the wrong cursor (not da), see: da.InsertCursor
    – BERA
    Jul 12 '19 at 19:20

Field mappings are painful, and to be avoided where possible. Therefore @BERA's alternative is a good method, and perhaps better than this one, but for the sake of completeness, here's how I use field mappings...

I have written a Python function that will generate a field mapping object simply by passing it the input feature class (or table) and a dictionary of source-field-names as keys and target-field-names as values. The function returns a field mapping object that can be used in an Append, etc:

def fmapForDict(inputDataset, mappingDict):
    fieldMappings = arcpy.FieldMappings()

    for sourceField in mappingDict:
        fMap = arcpy.FieldMap()
        fMap.addInputField(inputDataset, sourceField)
        outField = fMap.outputField
        outField.name = mappingDict[sourceField]
        fMap.outputField = outField

    return fieldMappings

NB: If your source fields and target fields all have the same names, then YOU DO NOT HAVE TO SUPPLY ANY FIELD MAPPINGS AT ALL. The arcpy.Append_management() function with a 'NO_TEST' argument, will automatically map any fields with matching field names (where possible).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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