I have a personal geodatabase with a polygon feature class with a one-to-many relationship to a table.
What I want to do is to export to a shapefile with all the infornation associated in every polygon.
I use ArcGis 10.2.1
I have a personal geodatabase with a polygon feature class with a one-to-many relationship to a table.
What I want to do is to export to a shapefile with all the infornation associated in every polygon.
I use ArcGis 10.2.1
I have used this script in the past. It is designed to work in ArcMap where you select records and it will select all related records and export to a new feature class, creating duplicate geometries for each related record.
import arcpy, os, sys
arcpy.env.ovewriteOutput = True
arcpy.env.qualifiedFieldNames = False
def SelectRelatedRecords(in_ft, in_field, rel_table, rel_field, sql='',export=False, out_fc=''):
'''
Selects all features from input layer based on selection from another table. Acts like
a "relationship class". There must be a common field between the two tables.
in_ft = input features
in_field = field for the relate from input features
rel_table = related table
rel_field = related table field
sql = where clause for the input features (optional)
export = Boolean option to export related records. Default is False.
out_fc = Output feature class. This parameter is only enabled
if export is True.
'''
# Check to make sure field types match, otherwise raise error and exit tool
in_ft_desc = arcpy.Describe(in_ft)
ftype1 = [f.type for f in in_ft_desc.fields if f.name == in_field][0]
ftype2 = [f.type for f in arcpy.Describe(rel_table).fields if f.name == rel_field][0]
if ftype1 != ftype2:
arcpy.AddError('\nField type for "{0}" in "{1}" does not match field type for "{2}"' \
' in "{3}"!\n'.format(in_field,in_ft,rel_field,rel_table))
arcpy.AddError('Field type is "{0}", must be "{1}".\n'.format(ftype1,ftype2))
sys.exit()
# map doc
mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd)[0]
# determine version for cursor type
ver = arcpy.GetInstallInfo()['Version']
if ver != '10.0':
dataAccess = True
else:
dataAccess = False
# make feature layer if sql
if sql not in ('', '#'):
arcpy.SelectLayerByAttribute_management(in_ft, 'NEW_SELECTION', sql)
sel_count = int(arcpy.GetCount_management(in_ft).getOutput(0))
arcpy.AddMessage('\n{0} selected records from from "{1}"\n'.format(sel_count, in_ft))
# grab unique id's
if dataAccess:
with arcpy.da.SearchCursor(in_ft, ['SHAPE@', in_field]) as rows:
geom_dict = dict((r[1], r[0]) for r in rows)
else:
rows = arcpy.SearchCursor(in_ft)
geom_dict = dict((r.getValue(in_field), r.shape) for r in rows)
del rows
# get keys
if ftype1 == 'String':
recs = tuple(filter(None, [k.encode('utf-8') for k in geom_dict.keys()]))
else:
recs = tuple(filter(None, geom_dict.keys()))
# Select records in related table
rel_path = os.path.dirname(arcpy.Describe(rel_table).catalogPath)
where = ''' {0} in {1} '''.format(arcpy.AddFieldDelimiters(rel_path, rel_field), recs)
arcpy.SelectLayerByAttribute_management(rel_table, 'NEW_SELECTION', where)
rel_count = int(arcpy.GetCount_management(rel_table).getOutput(0))
arcpy.AddMessage('Selected {0} related records from "{1}"\n'.format(rel_count, rel_table))
# if export is true, create output features
if export in [True,'true',1]:
if out_fc:
# See if there are many to one relationships
if rel_count > sel_count:
# get counts of keys
if dataAccess:
with arcpy.da.SearchCursor(rel_table, [rel_field]) as rows:
recs2 = [r[0] for r in rows]
else:
rows = arcpy.SearchCursor(rel_table)
recs2 = [r.getValue(rel_field) for r in rows]
del rows
# get counts
features = []
for rec in recs:
for i in range(recs2.count(rec)):
features.append((geom_dict[rec], rec))
# make new feature class
tmp = r'in_memory\tmp_lyr_xyz123'
sType = in_ft_desc.shapeType.upper()
path, name = os.path.split(tmp)
arcpy.CreateFeatureclass_management(path, name, sType, '', '', '',
in_ft_desc.spatialReference)
f_length = [f.length for f in in_ft_desc.fields if f.name == in_field][0]
tmp_field = 'TMP_JN_XYZ'
arcpy.AddField_management(tmp, tmp_field, ftype1, field_length=f_length)
# insert geometry
if dataAccess:
with arcpy.da.InsertCursor(tmp, ['SHAPE@', tmp_field]) as irows:
for feats in features:
irows.insertRow(feats)
else:
irows = arcpy.InsertCursor(tmp)
for feats in features:
irow = irows.newRow()
irow.shape = feats[0]
irow.setValue(tmp_field, feats[1])
irows.insertRow(irow)
del irow, irows
# Make feature layer and add join
tmp_lyr = str(arcpy.MakeFeatureLayer_management(tmp, 'temp_for_join').getOutput(0))
arcpy.AddJoin_management(tmp_lyr, tmp_field, rel_table, rel_field)
arcpy.CopyFeatures_management(tmp_lyr, out_fc)
# Clean up
for t in [tmp, tmp_lyr]:
arcpy.Delete_management(t)
arcpy.DeleteField_management(out_fc, [tmp_field])
# Export results
arcpy.AddMessage('Exported {0} Selected features '\
'to: {1}'.format(int(arcpy.GetCount_management(out_fc).getOutput(0)), out_fc))
else:
# Join records and export to new feature class
arcpy.AddJoin_management(in_ft, in_field, rel_table, rel_field)
arcpy.CopyFeatures_management(in_ft, out_fc)
arcpy.RemoveJoin_management(in_ft, rel_table)
# Export results
arcpy.AddMessage('Exported {0} Selected features '\
'to: {1}'.format(int(arcpy.GetCount_management(out_fc).getOutput(0)), out_fc))
# Zoom to selected features
df.zoomToSelectedFeatures()
arcpy.RefreshActiveView()
return
if __name__ == '__main__':
# Run it
SelectRelatedRecords(*sys.argv[1:])