I'm a python beginner.
I`m 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)
-
Possible duplicate of Getting values from attribute table and inserting another table using ArcPy?Erica– Erica2016年01月05日 18:20:05 +00:00Commented Jan 5, 2016 at 18:20
-
Write values based on what? do you need to match values in table b or just create b as a copy of a?jbchurchill– jbchurchill2016年01月05日 18:53:26 +00:00Commented Jan 5, 2016 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– user639642016年01月05日 19:06:03 +00:00Commented Jan 5, 2016 at 19:06
1 Answer 1
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
def flattenTable(table, new_fc, read_field='STNAMES', new_field='JOIN_NAMES'):
# 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)
# add new field
fields = ['SHAPE@'] + [f.name for f in arcpy.ListFields(table) if f.type not in ('OID','Geometry')]
f_index = fields.index(read_field)
arcpy.management.AddField(new_fc, new_field, 'TEXT', field_length=100)
# 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
arcpy.AddMessage(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
add_fields = ['QUADNAME', 'MAPNUM', 'EAM_STATUS', 'EAM_POSITION_ID'] #fields from join table to add
# run it
CopyFields(target_table, target_join_field, join_table, join_field, add_fields)