Update Cursor on Join Tables

2307
6
Jump to solution
06-27-2019 08:41 PM
deleted-user-yC5VkbyXzrQR
Occasional Contributor

Hello, 

So I'm having a hard time trying to figure how to do this script. I almost have it figured out I'm just missing something. 

 I figured out that you can't use CursorUpdate with a join table so I'm doing a work around that I found on other forums. 

Trying to do this:

1. Download Parcels from Hosted Feature Layer from ArcGIS Online (completed)

2. Compare the Hosted Feature Layer to our parcel database (exact same dataset). 

3. Find the differences in the "Status" Field and update our database with the new "Status" field from the Hosted Layer.

4. Keep track of what parcels have changed in a list. 

Below is what I thought it would work but it prints all yes for every single parcel and not the ones where the Status is differnt. (i'm just using print yes, Not updating them until I get this part figured out)

hostedfc = dict([(r[0], (r[1])) for r in arcpy.da.SearchCursor("testingg_3", ["APN","Status_5"])])  
  
  
with arcpy.da.UpdateCursor("testingg_2", ["APN","Status_5"]) as cursor:  
	for row in cursor:  
		if hostedfc[keys] in row[0] and row[1] != hostedfc[values]:
			print "yes"

Am I on the right track? I've spent hours trying to figure this part out. 

0 Kudos
1 Solution

Accepted Solutions
RandyBurton
MVP Alum

Looks like you are trying to accomplish what Richard Fairhurst‌ is describing in his blog: Turbo Charging Data Manipulation with Python Cursors and Dictionaries.  See his code for Example 1.

View solution in original post

6 Replies
JoshuaBixby
MVP Esteemed Contributor

Where is keys being defined?  You are using it in Line #6, but it isn't defined anywhere in the code snippet you provide.

0 Kudos
deleted-user-yC5VkbyXzrQR
Occasional Contributor

Thanks for the reply Joshua. 

hmmm, I thought I was defining the keys and values in line 1. 

hostedfc = dict([(r[0], (r[1])) for r in arcpy.da.SearchCursor("testingg_3", ["APN","Status_5"])])

If I just run that line of code. And then type in "hostedfc"

I get the whole dictionary to populate with The key: APN and the Value is Status_5

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

The link you quote creates and populates the dictionary, including keys.  That said, you do not access the keys by dict[keys].  The syntax is dict.keys().

RandyBurton
MVP Alum

Looks like you are trying to accomplish what Richard Fairhurst‌ is describing in his blog: Turbo Charging Data Manipulation with Python Cursors and Dictionaries.  See his code for Example 1.

deleted-user-yC5VkbyXzrQR
Occasional Contributor

Nice Randy! This was exactly what I was looking for! 

0 Kudos
JoeBorgione
MVP Emeritus

I try to be a little more explicit when using dictionaries as update sources, and following the turbo charging approach Randy Burton‌ mentions above, just yesterday I was working on this def():

import arcpy, decimal
decimal.getcontext().prec=3
from decimal import Decimal

def updateField():

    
    outSDE = r'I:\GIS\arcsde\SuperUser\slcogis\gdb_AG\gdb_AG@slcogisTEST.sde'
    
    
    targetFC = r'I:\GIS\arcsde\SuperUser\slcogis\gdb_AG\gdb_AG@slcogisTEST.sde\SLCOGIS.GDB_AG.ClientsDeliveries_2019'
    targetFields =  ['Zipcode','ClientCount','PercentPopServed']
    
    popSrcTable = r'I:\GIS\ArcSDE\SuperUser\slcogis\gdb_AG\gdb_AG@slcogisTEST.sde\SLCOGIS.GDB_AG.Over60Population_2018' #'{}\SLCOGIS.GDB_AG.Over60Population2018'.format(outSDE)
    popSrcFields = ['ID', 'TotalOVer60']
    
    edit = arcpy.da.Editor(outSDE)
    edit.startEditing(False, False)
    edit.startOperation()
    
    #create dictionary....
    popDict = {r[0]:(r[1]) for r in arcpy.da.SearchCursor(popSrcTable,popSrcFields)}
    
    try:
        with arcpy.da.UpdateCursor(targetFC,targetFields) as updateCursor:
            for updateRow in updateCursor:
                keyValue = updateRow[0]
                if keyValue == None:
                    pass
                elif keyValue in popDict:
                    client = (updateRow[1])
                    pop = popDict.get(keyValue,[0])
                    newValue = Decimal(client)/Decimal(pop)*100
                    updateRow[2] = newValue
                    updateCursor.updateRow(updateRow)
            print('Success: mergeClientToDelivery updated fields in deliveries table in memory')
            edit.stopOperation()
            edit.stopEditing(True)
    except Exception as err:
        print('Error: mergeClientToDelivery could not update deliveries table in memory')
        print(err)
        #sendEmail(err)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I have a table of population data referenced as popSrcTable that has a Zipcode field (ID)  and the Population of that zipcode (TotalOVer60) and I need to ratio that population value to the number of Clients served (ClientCount) to get a percentage (PercentPopServed) updated in the target feature class.

First step is to create the dictionary of the population data in the form of

{'84009': 2818,'84006': 145,'84084': 4788,'84113': 14.....}

Where the keys values are zipcode, and the associated values are the population. Line 30 is where things get interesting: there it checks for the presence of the zipcode in my target (updateRow[0]).  Line 31 gets the number of clients((updateRow[1]). Line 32 is where I 'get' the value of the population for the given zipcode; that's the linch pin when using  dictionary.  Finally I do a little math and update...

In my case the dictionary is simple: 1 key, 1 value, but you could have multiple values to a single key and update multiple fields if you need to.

That should just about do it....
0 Kudos