# Arcpy search cursor and update cursor to write values from table A to table B

I'm a python beginner.

Im working with ArcGIS 10.2.2 and IDLE Python 2.7.5

I have two tables, table A (top) and table B.

I need to read the attributes for the A-table fields for the selected record and write the fields and their attributes to all rows of the B table. I need the same attribute information for each row the fields.

I'm working with something like this

   with arcpy.da.UpdateCursor(fc2, field3) as cursor:
for row in cursor:
row[0] = 'Q'
cursor.updateRow(row)
with arcpy.da.UpdateCursor(fc2, field4) as ucursor:
with arcpy.da.SearchCursor(fc2, field5) as scursor:
for srow in scursor:
sval = srow[0]
urow = ucursor.next()
urow[0] = "0" + sval.replace("-", "")
ucursor.updateRow(urow)

• Write values based on what? do you need to match values in table b or just create b as a copy of a? – jbchurchill Jan 5 '16 at 18:53
• I need an exact copy of A table (for the seleted record) for both of B's records. I've comptely read the cursor help docs and they don't have the syntax I need I'm working with something like this but it only works for two tables that have equal numbers of records and fields: – user63964 Jan 5 '16 at 19:06

I have a function I call all the time for doing this, but first, you'll need a common field to join by. From the screenshot, looks like you have a one to many relationship between the fields with several road names ('{DEER HOLLOW WAY}{HUNTERS GLEN WAY}{HUNTERS GLEN WAY}') and those with single field names ('DEER HOLLOW WAY'). You'll want to make a field that you can use to match to the records in the second table. You may want to separate this out to a 1 to 1 relationship in a new table like this:

import os
import arcpy

# make a copy of schema
desc = arcpy.Describe(table)
where = '{} < 0'.format(arcpy.AddFieldDelimiters(table, desc.OIDFieldName))

path, name = os.path.split(new_fc)
arcpy.conversion.FeatureClassToFeatureClass(table, path, name, where)

fields = ['SHAPE@'] + [f.name for f in arcpy.ListFields(table) if f.type not in ('OID','Geometry')]

# search and insert cursors
used = []
with arcpy.da.InsertCursor(new_fc, fields + [new_field]) as irows:
with arcpy.da.SearchCursor(table, fields) as rows:
for r in rows:
st_names = set(filter(None, map(lambda x: x.strip('}'), r[f_index].split('{'))))
# make overlapping features to flat 1M to 1 to 1 relationship
for st in st_names:
if st not in used:
irows.insertRow(r + (st,))
used += list(st_names)  # supress duplicates
return new_fc

if __name__ == '__main__':

table = r'C:\Path\to_your\create_position.shp'
new_fc = r'C:\Path\to_your\create_position_1to1.shp'

# change field variables if necessary

# run it
flattenTable(table, new_fc) #optional args for field names can be added


And finally, after you have added a common "join_field", you can call this function to add the fields. Be sure to change the variables under the __main__ block appropriately.

import arcpy
import os

FIELD_TYPES = {
'Date':'DATE',
'String':'TEXT',
'Single':'FLOAT',
'Double':'DOUBLE',
'SmallInteger':'SHORT',
'Integer':'LONG',
'GUID':'GUID',
'Raster':'RASTER'
}

def CopyFields(source_table, in_field, join_table, join_key, join_values=[]):
"""
Copies field(s) from one table to another

Required:
source_table -- table in which to add new fields
in_field -- a field that has common values to a field in the join_table.
think of this as a "join_field"
join_table -- table with fields to add to source_table
join_key -- field to match values of the "in_field"
join_values -- fields to add to source_table (list)
"""

def Message(msg):
print msg

# Get Catalog path (for feature layers and table views)
cat_path = arcpy.Describe(source_table).catalogPath

# Find out if source table is NULLABLE
if not os.path.splitext(cat_path)[1] in ['.dbf','.shp']:
nullable = 'NULLABLE'
else:
nullable = 'NON_NULLABLE'

# Add fields to be copied
update_fields = []
join_list = [f for f in arcpy.ListFields(join_table)
if f.type not in('OID', 'Geometry')]
for field in join_list:
ftype = field.type
name = field.name
length = field.length
pres = field.precision
scale = field.scale
alias = field.aliasName
domain = field.domain
for fldb in join_values:
if fldb == name:
arcpy.AddField_management(source_table,name,FIELD_TYPES[ftype], pres, scale, length, alias, nullable, '', domain)
Message("Added '%s' field to \"%s\"" %(name, os.path.basename(source_table)))
update_fields.insert(join_values.index(fldb), name.encode('utf-8'))

# update new fields
#
# Create Dictionary
with arcpy.da.SearchCursor(join_table, [join_key] + join_values) as srows:
path_dict = {r[0]: r[1:] for r in srows}

# Update Cursor
with arcpy.da.UpdateCursor(source_table, [in_field] + update_fields) as urows:
for row in urows:
if row[0] in path_dict:
try:
row[1:] = path_dict[row[0]]
urows.updateRow(row)
except:
continue

Message('Fields in "%s" updated successfully' %(os.path.basename(source_table)))
return update_fields

if __name__ == '__main__':

target_table = r'C:\Path\to_your\targetTable.shp'
target_join_field = 'SOME_FIELD' # need to calculate this
join_table = r'C:\Path\to_your\joinTable.shp'
join_field = 'SOME_FIELD' # need to calculate this
`