Trying to add rows and update values using arcpy.da.InsertCursor

2540
2
Jump to solution
11-04-2013 12:08 PM
LeeBrannon
New Contributor III
In my code, I am creating duplicate polygons from existing polygons all within the same feature class.  I am passing all the attributes from the original polygon to the duplicate.  This works fine.

But what I cannot figure out is how to change one attribute value in the duplicate polygon while using the InsertCursor object that creates the duplicate polygon.  If I could get the InsertCursor object to do it (update the one attribute value) while inside the same For loop where the duplicate polygon is created - using inCur.insertRow(rowParcel), then it would make it very easy for me to assign the correct value to the duplicate polygon.  In the code below, the fsa variable has the value that needs to be inserted into the duplicate polygon.

import arcpy  # Set Geoprocessing environments arcpy.env.scratchWorkspace = "F:\\ArcGISServer\\DataProcessing\\Mobile_Parcels\\TestData\\Testing.gdb" arcpy.env.workspace = "F:\\ArcGISServer\\DataProcessing\\Mobile_Parcels\\TestData\\Testing.gdb" arcpy.env.overwriteOutput = True   # Add code to generate target address list (dataset) addrList_fc = "F:\\ArcGISServer\\DataProcessing\\Mobile_Parcels\\TestData\\Testing.gdb\\addresspts_LeftOut_tmpSel"  # Loop through the address list dataset created above; check for parcel# match against target parcels dataset from earlier script; # create duplicate parcel & populate FULL_ADD targetParcels = "F:\\ArcGISServer\\DataProcessing\\Mobile_Parcels\\TestData\\Testing.gdb\\target_parcels_sample"  cursor2 = arcpy.da.SearchCursor(targetParcels, ["ASSESSORSI", "*", "SHAPE@"])  ## Maybe use ["ASSESSORSI", "FULL_ADD", "*"] inCur = arcpy.da.InsertCursor(targetParcels, ["ASSESSORSI", "*", "SHAPE@"])  # Loop thru the address dataset with arcpy.da.SearchCursor(addrList_fc, ["PARCELNO", "FSA"]) as cursor1:       for rowAddr in cursor1:         # Grab the address value from address dataset         fsa = rowAddr[1]         cursor2.reset()         # Loop thru the parcel dataset         for rowParcel in cursor2:             if rowAddr[0] == rowParcel[0]:  # Compare parcel # values for a match                 # If there is a match, use current parcel record to create a duplicate parcel and insert the current address value                 # into the parcels FULL_ADD field (don't know how to accomplish this last part)                 inCur.insertRow(rowParcel)                 break  # and get out of inner For Loop and proceed back to outer For Loop             #else, continue with the next row in the inner For Loop        del cursor1, cursor2, inCur, rowParcel, rowAddr print "Script completed"


Thanks in advance for any help.
Lee
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
markdenil
Occasional Contributor III
I cannot help thinking that this script is a tad overelaborate.
Who was the Spanish king who, after the Ptolomaic cosmological system was explained to him,
remarked that "Had God first consulted him (the king) before building the universe,
he (the king) would have suggested something very much simpler"?

In any event,
A da search cursor returns a tuple, which is immutable.
You can, though, convert the tupple to a list, using
tmpList = list(rowParcel)

Now, since you know the position of the fsa item in the tupple (now a mutable list),
you can update it by index.
tmpList[fsaIndexPosition] = fsa

Now convert the list back into a tuple:
newRow = tuple(tmpList)

... and use the cursor to insert the tuple as a new row:
inCur.insertRow(newRow)

View solution in original post

0 Kudos
2 Replies
markdenil
Occasional Contributor III
I cannot help thinking that this script is a tad overelaborate.
Who was the Spanish king who, after the Ptolomaic cosmological system was explained to him,
remarked that "Had God first consulted him (the king) before building the universe,
he (the king) would have suggested something very much simpler"?

In any event,
A da search cursor returns a tuple, which is immutable.
You can, though, convert the tupple to a list, using
tmpList = list(rowParcel)

Now, since you know the position of the fsa item in the tupple (now a mutable list),
you can update it by index.
tmpList[fsaIndexPosition] = fsa

Now convert the list back into a tuple:
newRow = tuple(tmpList)

... and use the cursor to insert the tuple as a new row:
inCur.insertRow(newRow)
0 Kudos
LeeBrannon
New Contributor III
Much thanks Mark!!  Your coding advice worked perfect!  It was exactly what I needed to do.

Final code below.

import arcpy

# Set Geoprocessing environments
arcpy.env.scratchWorkspace = "F:\\ArcGISServer\\DataProcessing\\Mobile_Parcels\\TestData\\Testing.gdb"
arcpy.env.workspace = "F:\\ArcGISServer\\DataProcessing\\Mobile_Parcels\\TestData\\Testing.gdb"
arcpy.env.overwriteOutput = True


# Add code to generate target address list (dataset).
addrList_fc = "F:\\ArcGISServer\\DataProcessing\\Mobile_Parcels\\TestData\\Testing.gdb\\addresspts_LeftOut_tmpSel"

# Loop through the address list dataset created above; check for parcel# match against target parcels dataset from earlier script;
# create duplicate parcel & populate FULL_ADD
targetParcels = "F:\\ArcGISServer\\DataProcessing\\Mobile_Parcels\\TestData\\Testing.gdb\\target_parcels_sample"

cursor2 = arcpy.da.SearchCursor(targetParcels, ["ASSESSORSI", "*", "SHAPE@"])
inCur = arcpy.da.InsertCursor(targetParcels, ["ASSESSORSI", "*", "SHAPE@"])

# Loop thru the address dataset
with arcpy.da.SearchCursor(addrList_fc, ["PARCELNO", "FSA"]) as cursor1:  
    for rowAddr in cursor1:
        # Grab the address value from address dataset
        fsa = rowAddr[1]
        cursor2.reset()
        # Loop thru the parcel dataset
        for rowParcel in cursor2:
            if rowAddr[0] == rowParcel[0]:  # Compare parcel # values for a match
                # If there is a match, use current parcel record to create a duplicate parcel and insert the current address value
                # into the parcels FULL_ADD field.

                # Convert the row tuple to a list so values can be changed
                tmpList = list(rowParcel)
                # Update the situs address value in the list
                tmpList[11] = fsa
                # Now convert the list back into a tuple
                dupRow = tuple(tmpList)
                
                inCur.insertRow(dupRow)
                break  # and get out of inner For Loop and proceed back to outer For Loop
            #else, continue with the next row in the inner For Loop

del cursor1, cursor2, inCur, rowParcel, rowAddr
print "Script completed"


Lee
0 Kudos