1

Some time back I had a requirement to develop an automated method (Python) to update field values for a spatial points dataset in an Oracle 11g SDE database (exported to GDB for testing). Im Using Win 7, ArcGIS 10.2, Python 2.7.5. The requirement was to create a selection of duplicated records and distribute the export to other offices for recipients to mark the rows as either KEEP or RETIRE and return the extract (csv) to me.

The idea was that I could then use csv.dictreader to import the results from the 2 required columns ('book_id' and 'book_ref') in the csv, keeping only results that met the criteria = 'KEEP'. I then wanted to pass those results to my feature class with further refinement only updating the existing values where the csv file 'book_id' number matched the feature class 'book_id'.

I ended up doing the task manually as i couldnt get a result from code despite researching the ArcGIS help section, hundreds and hundreds of posts on this site, geonet, arcpy cafe etc, etc.

Eventually though I cobbled enough bits together to make it work oustide of work then thought I would post the solution in case others had similar needs.

0
     123.csf file contents;
     book_id    TYPE    book_ref    Status   POINT_X         POINT_Y
     2397        3       3645        Keep   9526430.185   4363958.707
     9644        12      2584        Keep   9526427.129   4363961.326
     9295        4       4427        Retire 9526421.019   4363963.072
     4406        3       3333        Keep   9526461.894   4363968.266
     1798        4       1832        Retire 9526461.457   4363974.813
     7643        4       1594        Keep   9526407.489   4363966.127
     6778        3       8582        Retire 9526412.29    4363968.746
     2252        3       3574        Keep   9526367.183   4363972.194
     7910        4       5648        Retire 9526402.746   4363934.921
     7588        3       9873        Keep   9526401.436   4363928.375


    # import modules
    import arcpy, csv
    # Set the workspace environment
    arcpy.env.workspace = "C:/Data/Code/Python/Library/Peter/MASTER_02.gdb"
    ws = arcpy.env.workspace
    arcpy.env.overwriteOutput = True
    print "Env.workspace set to: '" +ws+ "'" '\n'
    #feature class
    in_fc1 = "C:/Data/Code/Python/Library/Peter/MASTER_02.gdb/ZONES/Shelves"
    print "Feat_Class: " +str(in_fc1)+ "\n"

    # What needs doing starts here......
    Att_Dict ={}
    with open ("C:/Data/Code/Python/Library/Peter/123.csv") as f:
        reader = csv.DictReader(f)
        for row in reader:
            if row['Status']=='Keep':
                Att_Dict.update({row['book_id']:row['book_ref']})                    

    print "Att_Dict: " + str(Att_Dict)+ "\n"               
    # Correctly imports the values as "Att_Dict" that I am after from the 123.csv = ....
    # {'7643': '7625', '2397': '1835', '7588': '9681', '9644': '2289', '4406': '4443', '2252': '7947'}

    Att_List = []
    for key, value in Att_Dict.items():   
        Att_List.append([int(key), int(value)])

    print "Att_List: " + str(Att_List)+ "\n"
    # Correctly reformats the Att_Dict values as Att_List for updating ....
    # [[7643, 7625], [2397, 1835], [7588, 9681], [9644, 2289], [4406, 4443], [2252, 7947]]

    for pair in Att_List:
        Att_Dict[pair[0]] = pair[1]

    fn1 = 'book_id'         # field name 1
    fn2 = 'book_ref'        # field name 2
    fields1 = [fn1, fn2]    # format works with da.UpdateCursor

    with arcpy.da.UpdateCursor(in_fc1, fields1) as cursor:
        for row in cursor:
            pos_1 = row[0]                  # pos_1 equates to record at row[0] ('book_id') column in fc "Shelves"
            if pos_1 in Att_Dict:           # if record row[0] ('book_id') column also exists in the Att_Dict, 
                row[1] = Att_Dict[pos_1]    # get the matching row[1] 'book_ref' value and overwrite the row in fc "Shelves"
                cursor.updateRow(row)       # perform the update

    # Delete cursor and row objects to remove locks on the data
    del row, cursor

    # And finishes here.....

The code is a copy and paste not a retype so nothing missing and it worked with my varaibles right now. Most importantly it meets my requirements albeit after the event. It may not be the most elegant code but it works and maybe others can get some value from it.

EDIT

Note if you're working in SDE, I found I had to add an edit session. # What needs doing starts here...... Att_Dict ={}

I modified to

    # What needs doing starts here......
    # Start an edit session. Must provide the worksapce.
    edit = arcpy.da.Editor(ws)
    # Edit session is started without an undo/redo stack for versioned data
    #  (for second argument, use False for unversioned data)
    edit.startEditing(False, False)
    # Start an edit operation
    edit.startOperation()
    Att_Dict ={}

and this before the # And finishes here.....

    # Delete cursor and row objects to remove locks on the data
    del row, cursor
    # Stop the edit operation.
    edit.stopOperation()
    # Stop the edit session and save the changes
    edit.stopEditing(True)
    # And finishes here.....
  • See update if working in SDE. – user1995458 Sep 21 '15 at 2:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.