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)
Solved! Go to Solution.
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()
The issue (I guess) is that you're trying to access a property of the describe table object that just doesn't exist.
dsc.Field1AFieldName
The field Field1A doesn't exist in the source table only in the target. I guess I was thinking that line 12& 13 would take care of that issue for both the Source SearchCuror and the Target InsertCursor.
you've created a describe object of the Target table then are trying to access a property of that describe object dsc.Field1AFieldName which doesn't exist and is causing the error. Line 12 imho is the issue.
I concur with @DavidPike . You're trying to reference fields as if there were a join, but there isn't one.
So can Field1A be skipped/not included when you pass the InsertCurosr, if so how?
@2Quiker wrote:So can Field1A be skipped/not included when you pass the InsertCurosr, if so how?
Sure, just leave that field out of the field_names parameter when you open the cursor. You only need to pass back values for the fields that you opened the cursor with.
I guess I was completely over thinking it.
dsc = arcpy.Describe(Source)
fields = dsc.fields
#out_fields = [dsc.OIDFieldName]
fieldnames = [field.name for field in fields]
lstFields = [field.name for field in fields]
with arcpy.da.SearchCursor(Source,fieldnames) as sCur:
with arcpy.da.InsertCursor(Target,lstFields) as iCur:
for row in sCur:
iCur.insertRow(row)
There's still some redundancy in your code. You can build a list of field names easily this way:
fieldnames = [f.name for f in arcpy.ListFields(Source)]
But this is getting all the field names. If you want to exclude something, you could do something like:
ignore_fields = ["Field1A", "SomethingElse"]
fieldnames = [f.name for f in arcpy.ListFields(Source) if f.name not in ignore_fields]
As a final note, it looks like you're just straight copying data; might I recommend Append()?
Thank you for the replies, after looking at the data a little I was wrong, I was working with the wrong data sorry about that.
So the Source table has OBJECTID_1(not sure way but this is how I get the data) and the target has OBJECTID. So the InsurtCur 'Cannot find field 'OBJECTID_1'. The Source OBJECTID_1 should go into the targets OBJECTID but as I said it can't find it. Maybe I am still over thinking it...
If I use append would the ObjectID vs ObjectID_1 be an issue?
I was trying use understand search and insert cursors to understand them better.