Solved! Go to Solution.
I'll go with the append.
Don't!
Going the Python route (reading the join tables(s) into a dictionary using a search cursor and then updating the main table via an update cursor is by far the fastest method. This is true in v10.0 and below, but is especially true in v10.1+ using ethe data access cursors. In addition to faster processing, this method is far more flexible in that allows for all sorts of error handeling and whatnot through conditional expressions.
For example, say you want to get the fields "ADDRESS" and "CITY" into the main table (key field being "NAME"):lutTbl = r"C:\temp\test.gdb\lookuptable" mainTbl = "r"C:\temp\test.gdb\maintable" lutDict= dict([(r[0], (r[1], r[2])) for r in arcpy.da.SearchCursor(lutTbl, ["NAME","ADDRESS","CITY"])]) arcpy.AddField_managment(mainTbl, "ADDRESS", "TEXT", "", "", "75") arcpy.AddField_managment(mainTbl, "CITY", "TEXT", "", "", "30") updateRows = arcpy.da.UpdateCursor(mainTbl, ["NAME","ADDRESS","CITY"]) for updateRow in updateRows: nameValue = updateRow[0] if nameValue in lutDict: updateRow[1] = lutDict[nameValue][0] #Address updateRow[2] = lutDict[nameValue][1] #City else: print "Could not locate address/city info for " + str(nameValue) updateRows.updateRow(updateRow) del updateRow, updateRows
Does the key value have to be unique?
...what happens if there are two people named John Smith that have different addresses in the look up table?
compKeyDict = {('smith, john', 1): "cat street", ('smith, john', 2): "dog street"} compValDict = {'smith, john': ["cat street", "dog street"]}
To answer some of your questions:
Yes. But you can use tuples as keys as well (aka a composite key) - which of course also have to be unique.
You have to get creative - I routinely deal with one to many or many to manys by using either composite keys and/or composite look up values. A basic example:compKeyDict = {('smith, john', 1): "cat street", ('smith, john', 2): "dog street"} compValDict = {'smith, john': ["cat street", "dog street"]}
I would put a wager in that anything (well pretty much anything) you can do in a RDBMS you can also do much faster and cheaper using dictionaries. All it takes is imagination and a lot of conditional expressions!
If it helps, here's a practical example of making use of a composite value dictionary where the sorted order of the many values are important to the overal analysis: http://forums.arcgis.com/threads/89835-brainteaser-viewshed-wind-turbines-the-more-you-see-the-worse...
You have to get creative - I routinely deal with one to many or many to manys by using either composite keys and/or composite look up values. A basic example:compKeyDict = {('smith, john', 1): "cat street", ('smith, john', 2): "dog street"} compValDict = {'smith, john': ["cat street", "dog street"]}
compKeyDict = {('smith, john', 1): "cat street", ('smith, john', 2): "dog street", ('smith, jack', 1): "clown street"} johnSmithKeysList = [key for key in compKeyDict if "smith, john" == key[0]]
can the composite key approach involve a list of items, or is it limited to single values and tuples?
testList = [1,2,3,4] testTuple = tuple(list)
import arcpy dbf = r'C:\TEMP\Test_Table.dbf' # Get Unique names fields = [f.name for f in arcpy.ListFields(dbf) if f.type != 'OID'] with arcpy.da.SearchCursor(dbf, fields) as rows: table = list(r for r in rows) # table as tuple names = list(set(r[0] for r in table)) # New dictionary people_dict = {} # Make each unique name the key # return all matches as list for values for name in names: people_dict[name] = [r for r in table if r[0] == name] # print matching records for each name for name,matches in people_dict.iteritems(): print name,matches print '\n\n'
Alex Olsen [(u'Alex Olsen', u'516 N Main St', u'West Branch', 61500.0)] Shelly Fields [(u'Shelly Fields', u'618 N Ward St', u'Macomb', 53500.0)] John Smith [(u'John Smith', u'1321 400th St', u'Tipton', 54000.0), (u'John Smith', u'222 E Third St', u'Lisbon', 47800.0), (u'John Smith', u'212 S 1st St', u'Tipton', 80000.0)] Steve Johnson [(u'Steve Johnson', u'447 S Fisk St', u'Macomb', 43400.0), (u'Steve Johnson', u'214 S 1st St', u'Tipton', 72000.0)]
# print all address, city for each match to name for name,matches in people_dict.iteritems(): print name, [(mat[1],mat[2]) for mat in matches] print '\n\n'
# print address,city for John Smith for name,attributes in people_dict.iteritems(): if name == 'John Smith': for att in attributes: print att[1:3]
# Get sum of income for each name for name,matches in people_dict.iteritems(): print name, sum(mat[-1] for mat in matches)