Field Mapping Help With Merge Tool

5352
15
03-21-2011 06:54 AM
LornaMurison
Occasional Contributor
Hello,
I'm new to python and using fieldmappings for the first time.
I have a script that creates two dBASE tables.  I would like one of the final steps in my script to be merging these two tables and keeping only two fields (UCID and Temp).  In the table "statTableV" these fields are "UCID" and "MEAN".  In the table "pointValuesV" these fields are "CATCH_02_3" and "RASTERVALU".  So I need to rename the fields and merge them.

I wrote the code below based on the code example provided here: http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?id=949&pid=944&topicname=Mapping_fields
but that is resulting in this error: ExecuteError: ERROR 000468: Input shape types are not equal
Failed to execute (Merge).
Which brings me to my question:
a) What is causing the error?
b) Most of the fields in my input tables are ones I don't need.  Do I have to specify that they be removed in field mapping or with they be ignored if they are not specified in the code?

Thank-you

# Import Modules
import arcgisscripting

# Create geoprocessor object
gp = arcgisscripting.create (9.3)

# Get parameters
catchments = r"F:\Climate\test\Catchments.gdb\Catch_02AA"
#catchments = gp.GetParameterAsText(0)                                  # Feature Layer
watershed = "02AA"
#watershed = gp.GetParameterAsText(1)
idField = "UCID"
#idField = gp.GetParameterAsText(2)                                     # Field
climateRaster = r"F:\Climate\test\Climate.gdb\Avg_Temp_January"
#climateRaster = gp.GetParameterAsText(3)                               # Raster Layer
month = "January"
#month = gp.GetParameterAsText (4)                                      # String
workspace = r"F:\Climate\test\Climate.gdb"
#workspace = gp.GetParameterAsText (5)                                  # Workspace
outWorkspace = r"F:\Climate\test"
#outWorkspace = gp.GetParameterAsText (6)                               # Folder

statTable = "zStat" + month
statTableV = "zStat" + month + "V"
missingStats = "zStat" + month + "Missing"
points = month + "Point"
pointValues = month + "PointValue"
pointValuesV = month + "PointValuesV"
finalTable = month + "Averages" + watershed
gp.Workspace = workspace
gp.overwriteoutput = True

# Check-out the Spatial Analyst extension
gp.CheckOutExtension ("Spatial")

# Run Zonal Statistics As Table
gp.ZonalStatisticsAsTable_sa (catchments, idField, climateRaster, statTable, "DATA")

# Create a feature layer from the catchments
gp.MakeFeatureLayer_management (catchments, "layer", "", workspace, "")

# Join zonal statistics table to catchments layer
gp.AddJoin_management ("layer", idField, statTable, idField, "KEEP_ALL")

# Select and export the catchments that don't have any zonal statistics
gp.Select_analysis ("layer", missingStats, '"' + statTable + "." + idField + '"' + ' is null')

# Un-join zonal statistics table from catchments
gp.RemoveJoin_management ("layer", statTable)

# Convert the exported "missing stats" catchments to point centroids
gp.FeatureToPoint_management (missingStats, points, "INSIDE")

# Add the underlying temperature values to the points
gp.ExtractValuesToPoints_sa (points, climateRaster, pointValues, "INTERPOLATE", "VALUE_ONLY")

# Make table views from the zonal statistics and value to points tables
gp.MakeTableView_management (statTable, statTableV, "", workspace, idField + " " + idField + " VISIBLE, RASTERVALU Temp VISIBLE")
gp.MakeTableView_management (pointValues, pointValuesV, "", workspace, idField + " " + idField + " VISIBLE, MEAN Temp VISIBLE")

# Convert table views to dBASE tables
gp.TableToDBASE_conversion (statTableV, outWorkspace)
gp.TableToDBASE_conversion (pointValuesV, outWorkspace)

# Prepare the field maps for the final table
fieldMappings = gp.createobject ("FieldMappings")
fldmap_UCID = gp.createobject ("FieldMap")
fldmap_Temp = gp.createobject ("FieldMap")
vt = gp.CreateObject("ValueTable")
fieldMappings.AddTable(statTableV)
fieldMappings.AddTable(pointValuesV)
fldmap_UCID.AddInputField(statTableV, "UCID")
fldmap_UCID.AddInputField(pointValuesV, "CATCH_02_3")
fldmap_Temp.AddInputField(statTableV, "MEAN")
fldmap_Temp.AddInputField(pointValuesV, "RASTERVALU")
fld_UCID = fldmap_UCID.OutputField
fld_Temp = fldmap_Temp.OutputField
fld_UCID.Name = "UCID"
fld_Temp.Name = "Temp"
fldmap_UCID.OutputField = fld_UCID
fldmap_Temp.OutputField = fld_Temp
fieldMappings.AddFieldMap(fldmap_UCID)
fieldMappings.AddFieldMap(fldmap_Temp)
vt.AddRow(statTableV)
vt.AddRow(pointValuesV)

# Merge the two tables
gp.Merge_management (vt, finalTable, fieldMappings)

# Delete all the temporary datasets
gp.Delete_management (statTable)
gp.Delete_management (missingStats)
gp.Delete_management (points)
gp.Delete_management (pointValues)
gp.Delete_management (statTableV + ".dbf")
gp.Delete_management (pointValuesV + ".dbf")
Tags (2)
0 Kudos
15 Replies
LornaMurison
Occasional Contributor
I just switched "/" to "\\" and it works! So simple, thank-you so much.
I had a whole reply typed out, so I'll post it anyway in case anyone wants to know what I was trying to do:

You are almost correct
My two input tables and the fields I am interested in are as follows:
F:\Climate\test\zStatJanuaryV.dbf UCID, TempFloat
F:\Climate\test\JanuaryPointValuesV.dbf Catch_02_3, TempFloat2

output fields:
UCID = zStatJanuaryV.UCID and JanuaryPointValuesV.Catch_02_3
Temp = zStatJanuaryV.TempFloat and JanuaryPointValuesV.TempFloat2

TempFloat is MEAN converted to float precision 5 scale 1
TempFloat2 is RASTERVALU converted to float precision 5 scale 1
0 Kudos
MathewCoyle
Frequent Contributor
No problem, those kinds of things are a real pain to track down. Python takes things so literally sometimes.
0 Kudos
GraemeBrowning
Occasional Contributor III
A similar Question has just been posed in Stack Exchange GIS - thanks for having worked through this so thoroughly here so that I could offer your work as a possible/likely Answer.

I had major dramas with Field Mapping of Table To Table being unexpectedly reset in some very large models at 9.3 and was glad to see those resolved at 10.0.

- Graeme
0 Kudos
AdamCox1
Occasional Contributor II
I second that sentiment exactly.

I find it easier to just delete unwanted fields with something like this. To me it is more logical and faster from what I have tried it on.

ouput = #<feature class>
dropFields = list()
fieldList = gp.ListFields(output)
for f in fieldList:
    if f.name <> "BLOCKSTAGE" and f.type <> "OID" and f.type <> "Geometry":
        print "Adding field to drop list "+f.name
        dropFields.append(f.name)
    gp.DeleteField_management(output, dropFields)



Also, ensure that the fields you are merging are the same data type.



Hello, this looks very close to what I'm trying to do, and failing at.  Instead of hard-coding the values "BLOCKSTAGE", "OID", etc., I'm wondering if there is a way to get those values from a list of fields in another fc.  In other words, I'd like to check against one fc and then and then delete any duplicate fields before I merge the two.

Thanks for any help you can offer.
Adam
0 Kudos
MathewCoyle
Frequent Contributor
Hello, this looks very close to what I'm trying to do, and failing at.  Instead of hard-coding the values "BLOCKSTAGE", "OID", etc., I'm wondering if there is a way to get those values from a list of fields in another fc.  In other words, I'd like to check against one fc and then and then delete any duplicate fields before I merge the two.

Thanks for any help you can offer.
Adam


I'm not sure I follow 100% but something like this should get you on your way. You may need to switch around which field list you loop through and which fc you are deleting from.

fc_target = #fc1
fc_merge = #fc2

fc_target_fields = [field.name for field in arcpy.ListFields(fc_target)]
fc_merge_fields = [field.name for field in arcpy.ListFields(fc_merge)]

dropFields = list()
for field in fc_target_fields:
    if field in fc_merge_fields:
        print "Adding field to drop list %s" % field
        dropFields.append(field)
    arcpy.DeleteField_management(fc_target, dropFields)
0 Kudos
AdamCox1
Occasional Contributor II
Splendid, thanks a million.  Only thing I had to do was dedent the DeleteField line so that it did not try to run every time after checking each field.
0 Kudos