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.

enter image description here

I'm working with something like this

   with arcpy.da.UpdateCursor(fc2, field3) as cursor:
        for row in cursor:
            row[0] = 'Q'
    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("-", "")
  • 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

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


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

        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'
        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:
                    row[1:] = path_dict[row[0]]

    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)

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.