3

I coded the Update Cursor for automation of tedious data entry where I am applying a previous Survey Company Identification Data to STRUCTURES_15096.shp from "OFFICIAL_STRUCTURES2015.shp" and it keeps crashing ArcMap and returns a “none” value. (See Picture Below Code)

Description: This script compares the numeric IDs from STRUCTURES_15096.shp and "OFFICIAL_STRUCTURES2015.shp. If the IDs match then the values representing the previous company, the date of prior inspection, and the equipment used will populate from "OFFICIAL_STRUCTURES2015.shp attribute table to STRUCTURES_15096.shp

I am still new to coding and python.

Code:

import arcpy as ARCPY
from arcpy import env as ENV
    """
    =============================================================================
    UPDATE_STR.py 
    Created on:  2015-04-06
    Created by:  BS
    Usage:       Apply previous Survey Company Identification Data to STRUCTURES_15096.shp 
                 from "OFFICIAL_STRUCTURES2015.shp"
    Description: This script compares the numeric IDs from STRUCTURES_15096.shp
                 and "OFFICIAL_STRUCTURES2015.shp.  If a match the values representing
                 the company, the date of inspection, and the equipment used will populate
    from "OFFICIAL_STRUCTURES2015.shp attribute table to STRUCTURES_15096.shp

  ===============================================================================
    Environment
    ===========
    """
workspaceTEST = r"C:\Users\Jim\Desktop\TESTSTRM_SWR.gdb"
ENV.workspace = workspaceTEST

=========================================================================

    """
    Variable for Shapefiles
    =======================
    """
str15096 = workspaceTEST + "\STRUCTURES_15096"
strOffical = workspaceTEST + "\OFFICIAL_STRUCTURES2015"

=========================================================================

CURSOR CREATION AND UTILIZATION

    #searchCursor3 is used to search in "OFFICIAL_STRUCTURES2015" and associated with row3.
searchCursor3 = ARCPY.da.SearchCursor(strOffical, ["ID_NUMBER", "COLLECTION","COLLECTED_","COLLECTI_1"])  
    for row3 in searchCursor3:
        tempRow3_ID = row3[0]               #"ID_NUMBER is "
        tempRow3_DATE = row3[1]             #"COLLECTION" = Date
        tempRow3_COMP = row3[2]             #"COLLECTED_" = Company
        tempRow3_EQUIP = row3[3]            #"COLLECTI_1" = Equipment
#UPDATEstr15096 is used to update in "STRUCTURES_15096"
        UPDATEstr15096 = ARCPY.UpdateCursor(str15096) 
        for UPDATErow_1 in UPDATEstr15096:
            if UPDATErow_1.ID == tempRow3_ID:
        #Print Testing
                print "UPDATErow_1.ID: ", UPDATErow_1.ID , "=" , "tempRow3_ID: " , tempRow3_ID        
                print "UPDATErow_1.COLLECTED_BY: " , UPDATErow_1.COLLECTED_BY
                print "UPDATErow_1.COLLECTION_EQUIPMENT: " , UPDATErow_1.COLLECTION_EQUIPMENT
                print "UPDATErow_1.COLLECTION_DATE" , UPDATErow_1.COLLECTION_DATE
                UPDATErow_1.COLLECTED_BY = tempRow3_COMP
                UPDATErow_1.COLLECTION_EQUIPMENT = tempRow3_EQUIP
                if tempRow3_DATE != ("<null>" or " "):            
                    UPDATErow_1.COLLECTION_DATE = tempRow3_DATE
                    print "CHANGE --- UPDATErow_1.COLLECTED_BY: " , UPDATErow_1.COLLECTED_BY
                    print "CHANGE --- UPDATErow_1.COLLECTION_EQUIPMENT: " , UPDATErow_1.COLLECTION_EQUIPMENT
                    print "CHANGE --- UPDATErow_1.COLLECTION_DATE" , UPDATErow_1.COLLECTION_DATE
                print "CHANGE --- UPDATErow_1.COLLECTED_BY: " , UPDATErow_1.COLLECTED_BY
                print "CHANGE --- UPDATErow_1.COLLECTION_EQUIPMENT: " , UPDATErow_1.COLLECTION_EQUIPMENT
        del UPDATErow_1
        del UPDATEstr15096
    del tempRow3_ID
    del tempRow3_COMP
    del tempRow3_DATE
    del row3
    del searchCursor3

Print Test Result:

Print Test Result


After making suggested adjustments I am now receiving a new error associated with line 24:

Runtime error Traceback (most recent call last): File "", line 24, in RuntimeError: A column was specified that does not exist.

import arcpy as ARCPY
from arcpy import env as ENV
#===============================================================================
#Environment(s)
#==============
#**TEST ENV**
workspaceTEST = r"C:\Users\Jim\Desktop\TESTSTRM_SWR.gdb"
ENV.workspace = workspaceTEST
#Variables
#=========
#**TEST**
str15096 = workspaceTEST + "\STRUCTURES_15096"
strOfficial = workspaceTEST + "\OFFICIAL_STRUCTURES2015"
fieldsStrOfficial = ["ID_NUMBER", "COLLECTION","COLLECTED_","COLLECTI_1"]
fieldsStr15096 = ["ID", "COLLECTION_EQUIPMENT","COLLECTED_BY","COLLECTED_DATE"]
print "Updated STRUCTURES_15096" #Initial Print Test

=====================================================

CURSOR CREATION AND UTILIZATION

================================

# Used list comprehension to build a dictionary from a data access SearchCursor  
valueDictOfficialStr = {readRow3[0]:(readRow3[1:]) for readRow3 in ARCPY.da.SearchCursor(strOfficial, fieldsStrOfficial)}
searchCursor3 = ARCPY.da.SearchCursor(strOfficial, ["ID_NUMBER", "COLLECTION","COLLECTED_","COLLECTI_1"])  #Will be associated with row3.
with ARCPY.da.UpdateCursor(str15096, fieldsStr15096) as updateRows_Str15096:  
for updateRow1 in updateRows_Str15096:  
    # store the Join value of the row being updated in a keyValue1 variable  
        keyValue1 = updateRow1[0]
    # verify that the keyValue1 is in the Dictionary  
        if keyValue1 in valueDictOfficialStr:  
            print keyValue1
    # transfer the values stored under the keyValue from the dictionary to the updated fields.  
            if valueDictOfficialStr[keyValue1][2] != ("<null>" or " "):
                for nullNoMore in range (1,len(fieldsStr15096)): 
                    updateRow1[nullNoMore] = valueDictOfficialStr[keyValue1][nullNoMore-1]  
                    print updateRow1[nullNoMore]
                updateRows_Str15096.updateRow1(updateRow1)  
    del updateRow1
    del updateRows_Str15096
del valueDictOfficialStr
del searchCursor3

enter image description here

  • Is there a reason you are using the new cursors (arcpy.da) for reading but the old ones (arcpy) for the updating? I'm not sure what you mean by 'returning None.' Where None is shown in your screenshot is the data before it's updated, so I wouldn't be surprised by a null value (None). Where/when is it crashing? Can you narrow it down to a set of records? – Evil Genius Apr 14 '16 at 17:16
  • 1
    Welcome to GIS SE, what is the specific error message? Looks like you are just showing the various print statements. – artwork21 Apr 14 '16 at 17:50
  • Ha! I'm an idiot! I totally spaced on the data access in the update. I also misread my print statements so that is a goof as well. It's getting bogged down after about a dozen lines. – Beau Apr 14 '16 at 20:39
7

Never, never, never use embedded cursor loops. Never! It is bad for performance, memory, data safety, etc. It is very, very bad.

See my blog on Turbo Charging Data Manipulation with Python Cursors and Dictionaries. Load the look up table into a dictionary with a data access search cursor, then update the other table with an update cursor by matching it to the dictionary. Performance is fantastic, memory is conserved, data is safe (at least as safe as any update procedure can be).

The revised code to match your naming conventions is (I do not rename arcpy and env just to create capitalized versions, I would rename an import to shorten its import prefix):

import arcpy
from arcpy import env
#===============================================================================
#Environment(s)
#==============
#**TEST env**
workspaceTEST = r"C:\Users\Jim\Desktop\TESTSTRM_SWR.gdb"
env.workspace = workspaceTEST
#Variables
#=========
#**TEST**
str15096 = workspaceTEST + "\STRUCTURES_15096"
strOfficial = workspaceTEST + "\OFFICIAL_STRUCTURES2015"
fieldsStrOfficial = ["ID_NUMBER", "COLLECTION","COLLECTED_","COLLECTI_1"]
fieldsStr15096 = ["ID", "COLLECTION_EQUIPMENT","COLLECTED_BY","COLLECTION_DATE"]
print "Updated STRUCTURES_15096" #Initial Print Test
=====================================================
CURSOR CREATION AND UTILIZATION
================================
# Used list comprehension to build a dictionary from a data access SearchCursor  
valueDictOfficialStr = {readRow3[0]:(readRow3[1:]) for readRow3 in arcpy.da.SearchCursor(strOfficial, fieldsStrOfficial)}
with arcpy.da.UpdateCursor(str15096, fieldsStr15096) as updateRows_Str15096:  
    for updateRow1 in updateRows_Str15096:  
    # store the Join value of the row being updated in a keyValue1 variable  
        keyValue1 = updateRow1[0]
    # verify that the keyValue1 is in the Dictionary  
        if keyValue1 in valueDictOfficialStr:  
            print keyValue1
    # transfer the values stored under the keyValue from the dictionary to the updated fields.  
            if valueDictOfficialStr[keyValue1][2] != ("<null>" or " "):
                for nullNoMore in range (1,len(fieldsStr15096)): 
                    updateRow1[nullNoMore] = valueDictOfficialStr[keyValue1][nullNoMore-1]  
                    print updateRow1[nullNoMore]
                updateRows_Str15096.updateRow(updateRow1)  
del valueDictOfficialStr 
  • The cursor in the list comprehension lacks a with. Is that something to worry about? – Kirk Kuykendall Apr 14 '16 at 19:12
  • 1
    Not in the 1000s of times I have used this code in my nightly automated update processes. See Example 2 in the Esri help - pro.arcgis.com/en/pro-app/arcpy/data-access/… – Richard Fairhurst Apr 14 '16 at 19:14
  • Richard, Great to know! Adjusted the code. Liked you blog. New Delimma arose. – Beau Apr 14 '16 at 22:31
  • Is the New Delimma related or unrelated to this issue? Let me know if you are having problems getting the code to work the way you want. – Richard Fairhurst Apr 14 '16 at 22:37
  • It is the same Runtime Error that I previously mentioned. – Beau Apr 15 '16 at 12:58
0

Just a small thing. in addition to embedded cursor loops. Use os.path.join instead of adding text strings together.

workspaceTEST = r"C:\Users\Jim\Desktop\TESTSTRM_SWR.gdb"
ENV.workspace = workspaceTEST
str15096 = os.path.join( workspaceTEST,"STRUCTURES_15096")

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.