I am trying to work out a way to populate a series of shape files into a new set of Datasets and feature classes.
I have an external table of what the destination feature class field name should be and its corresponding source feature class/shape field name.
Assumptions: Destination feature class field order is not the same as the source field order (but the external table tells me the name at least)
Destination feature class field name is not necessarily the same as the source field name (but again the external table tells me what the equivalent map is)
I iterate through my destination database by dataset/feature class, then for each feature class I iterate through the fields. Then for each field, i match that dataset/featureclass/field combo on my external table (using a temporary table) to find what the equivalent source featureclass/field is.
Finally i try to build a field map of the appropriate fieldmappings in order to run an append command to populate the destination featureclass.
I am the first to admit I get ideas from lots of other people's code so learn on the fly and comment a lot in my code to try and understand what the script is doing so apologies in advance if it looks like a dogs breakfast but it is how I am trying to learn.
I am still getting a number of errors (i can't seem to reset the field maps for the next feature class for instance but i am not worried about that at the moment) but the main thing I am trying to work out is how to build the field mappings and am getting monumentally confused.
So far I Have gotten this far:
import arcpy
import os
arcpy.env.workspace = r"C:\1994 Schema.gdb"
SourceDataset = r"C:\GDA94"
DestinationDatabase = r"C:\1994 Schema.gdb"
xlsx = r"C:\Documents\ShapeFileToFeatureClassTableMap.xlsx"
TempTable = r"C:\Temp\ShapeFileToFeatureClassMap.dbf"
#delete the temp table if it is there still
if arcpy.Exists(TempTable):
arcpy.Delete_management(TempTable)
SourceFeatureClass = ""
fieldmappings = arcpy.FieldMappings()
DatasetList = arcpy.ListDatasets(wild_card = "*" , feature_type = "Feature")
arcpy.ExcelToTable_conversion(xlsx,TempTable,Sheet="Sheet1")
#iterate through each dataset
for DS in DatasetList:
FeatureClassList = arcpy.ListFeatureClasses(wild_card = "*" , feature_type = "All", feature_dataset = DS)
#iterate through each featureclass
for FC in FeatureClassList:
print ("DS: ",DS,", FC: ",FC)
#create the field list for the specific feature class we are dealing with
FieldsInDestinationFeatureClass = [f for f in arcpy.ListFields(FC) if f.name not in ("Shape", "OBJECTID", "Shape_Length" , "Shape_Area")]
for SpecificField in FieldsInDestinationFeatureClass:
print (SpecificField.name)
#run the fieldmap commands (I think)
MyFieldMap = arcpy.FieldMap()
MyFieldMap.addInputField(FC,SpecificField.name)
#look through my mapping table to find a match
with arcpy.da.SearchCursor(TempTable,["*"]) as AllRowsInTempTable:
for row in AllRowsInTempTable:
#row[0] dbf row counter (starts at 0 for first row)
#row[1] TargetDataset
#row[2] TargetFeatureclass
#row[3] TargetFieldName
#row[4] SourceFeatureclass
#row[5] SourceFeatureClassFieldName
#found a match (dataset, feature class and field name)
if row[1] == DS and row[2] == FC and SpecificField.name == row[3]:
print ("matchedrow is: ",row[0]) #matched row in the mapping table (note this is out by 2 as it appears to exclude headers and starts row counter at 0
if os.path.join(SourceDataset,row[4]) <> SourceFeatureClass:
print "Needing to change the source location to match what it should be"
SourceFeatureClass = os.path.join(SourceDataset,row[4])
print SourceFeatureClass
MyFieldMap.addInputField(SourceFeatureClass,row[5]) #suspect this is causing issues?
#add everything into the field mappings
fieldmappings.addFieldMap(MyFieldMap)
#print out the field mappings to see what is happening
Fieldmapstring = fieldmappings.exportToString()
print Fieldmapstring
print ("running append on target datset: ",FC)
arcpy.Append_management(SourceFeatureClass, FC, schema_type = "NO_TEST", field_mapping=fieldmappings)
print "reset field mappings"
fieldmappings.removeAll()
If i look how the field map builds after it has completed the construction, it comes out like this
ROW_ID "RowID" true true false 5 Text 0 0 ,First,#,C:\1994 Schema.gdb\Cemetery_Text,ROW_ID,-1,-1,C:\GDA94\Cemetery\Cemetery_Text.shp,ROW,-1,-1;AMENDATE "AmmendmentDate" true true false 8 Double 0 0 ,First,#,C:\1994 Schema.gdb\Cemetery_Text,AMENDATE,-1,-1,C:\GDA94\Cemetery\Cemetery_Text.shp,AMENDATE,-1,-1;PREVDATE "PreviousDate" true true false 8 Double 0 0 ,First,#,C:\1994 Schema.gdb\Cemetery_Text,PREVDATE,-1,-1,C:\GDA94\Cemetery\Cemetery_Text.shp,PREVDATE,-1,-1
However if i run the append inside Arc catalogue and see how it construct its own NO_TEST mapping, it looks like this:
ROW_ID "RowID" true true false 5 Text 0 0 ,First,#,C:\GDA94\Cemetery\Cemetery_Text.shp,ROW,-1,-1;AMENDATE "AmmendmentDate" true true false 8 Double 0 0 ,First,#,C:\GDA94\Cemetery\Cemetery_Text.shp,AMENDATE,-1,-1;PREVDATE "PreviousDate" true true false 8 Double 0 0 ,First,#,C:\GDA94\Cemetery\Cemetery_Text.shp,PREVDATE,-1,-1
So i can see with that first mapping: my generated map is different to the arc catalogue version
Arc catalogue version:
ROW_ID "RowID" true true false 5 Text 0 0 ,First,#,C:\GDA94\Cemetery\Cemetery_Text.shp,ROW,-1,-1;
My generated version:
ROW_ID "RowID" true true false 5 Text 0 0 ,First,#,C:\1994 Schema.gdb\Cemetery_Text,ROW_ID,-1,-1,C:\GDA94\Cemetery\Cemetery_Text.shp,ROW,-1,-1;
It seems to work ok up to the hashtag (which all looks like destination field property information), but then after the hash, i have both my destination featureclass path and the source featureclass path whereas the generated one doesn't.
I am now wondering if i should build the fieldmap as a text string if i know what each of the comma separations are? I have tried experimenting with .outputField but that affects the first bit of code rather than that final bit. Kind of running out of ideas trying to work out how to generate this field map and actually understand what it is doing.
Excel Mapping sheet has the following columns:
DatasetTarget | FeatureClassTarget | FeatureClassTargetField | FeatureClassSource | FeatureClassSourceField