Copy certain tabel fields and exclude field

1730
10
Jump to solution
06-21-2021 11:42 AM
2Quiker
Occasional Contributor II

I am trying to use InsertCurosr to transfer rows from one table to another. Yes I could just use append but I am trying to see if the InsertCurosr is faster but I am getting the error

"DescribeData: Method Field1AFieldName does not exist".

Here is what I have currently. The Source Label currently does not have Field1A, Target does have the Field1A field.

import arcpy,os
#### Transfer Source table rows into Target Table

arcpy.env.workspace = r'C:\Temp\Test.gdb'

Target = r"C:\Temp\Test.gdb\TargetTable"
Source = r"C:\Temp\Test.gdb\SourceTable"
arcpy.DeleteRows_management(Target)

dsc = arcpy.Describe(Target)
fields = dsc.fields
out_fields = [dsc.OIDFieldName, dsc.Field1AFieldName]
fieldnames = [field.name for field in fields if field.name not in out_fields]

with arcpy.da.SearchCursor(Source,fieldnames) as sCur:
   with arcpy.da.InsertCursor(Target,fieldnames) as iCur:
      for row in sCur:
          iCur.insertRow(row)

 

0 Kudos
10 Replies
BlakeTerhune
MVP Regular Contributor

The ObjectID_1 field most commonly happens when you import a feature class that already has an ObjectID field into a geodatabase, which tries to create its own OID field but since the default name is already taken, it names it with _1.

Because of the mismatched field names, you would need to create a field mappings object, which is a bit annoying for just one off-named field. You could recreate the feature class with only the one default named OID field so Append would work without field mappings, or use the cursors as you were attempting to do.

Here's what I would do for cursors

 

dsc = arcpy.Describe(Source)
target_field_Names = [f.name for f in arcpy.ListFields(Source)]
source_field_Names = [
    f.name for f in arcpy.ListFields(Source)
    if f.type != "OID"
    and f.name in target_field_Names
]
with arcpy.da.SearchCursor(Source,fieldnames) as sCur:
   with arcpy.da.InsertCursor(Target,lstFields) as iCur:
      for row in sCur:
          iCur.insertRow(row)

 

And here's what I would do for using append with field mappings. I created a fuzzy_fieldmap() function that will create field mappings only with fields that exist in both the source and target tables (excluding ObjectID fields).

 

import arcpy

def main():
    fieldmappings = fuzzy_fieldmap(sourceTable, targetTable)

    arcpy.Append_management(
        sourceTable,
        targetTable,
        "NO_TEST",
        fieldmappings
    )
    print(arcpy.GetMessages())


def fuzzy_fieldmap(input_table, target_table):
    input_fields = [
        f.name.upper() for f in arcpy.ListFields(input_table)
        if f.type != "OID" or f.name != "OBJECTID"
    ]

    target_fields = [
        f.name.upper() for f in arcpy.ListFields(target_table)
        if f.type != "OID" or f.name != "OBJECTID"
    ]
    # Main FieldMapings object to hold FieldMap objects
    fms = arcpy.FieldMappings()
    # dictionary for FieldMap objects
    fm_vars = {}

    for t_field in target_fields:
        if t_field in input_fields:
            # Create the FieldMap object
            fm_vars[t_field] = arcpy.FieldMap()
            # Add fields to FieldMap object
            # Add target field first so the output gets those field properties
            fm_vars[t_field].addInputField(target_table, t_field)
            fm_vars[t_field].addInputField(input_table, t_field)
            # Add the FieldMap objects to the FieldMappings object
            fms.addFieldMap(fm_vars[t_field])

    # Optional debugging section to print field mappings
    for out_field in fms.fields:
        print("{} ({}): {}".format(out_field.name, out_field.aliasName, out_field.type))

    return fms


if __name__ == '__main__':
    main()