RemoveAttachments_management doesn't remove all matched attachments

362
1
11-27-2019 06:55 AM
RemigijusPankevičius
New Contributor III

ArcMap 10.5, referred doc: Remove Attachments—Help | ArcGIS for Desktop 


I created a tool for users to attach files to the selected objects in ArcMap. However my efforts to protect from attaching the same file to the same file several times do not work, very often the duplicates appear.

The algorithm I use is pretty straightforward. If user selects 2 objects from one feature class with object IDs 10 and 20 and a file 'c:\folder\somefile.pdf' I do:
Create match table with fields ID(LONG) and FILEPATH(TEXT).
Fill table with short file name:
(10, 'somefile.pdf')
(20, 'somefile.pdf')
Run RemoveAttachments_management(featureClass, oidFieldName, matchTable, "ID", "FILEPATH")
Clear match table and fill it with full file name:
(10, 'c:\folder\somefile.pdf')
(20, 'c:\folder\somefile.pdf')
Run AddAttachments_management(featureClass, oidFieldName, matchTable, "ID", "FILEPATH")

However, it turns out that RemoveAttachments_management doesn't remove all matched attachments, just the first one. I extracted code as a standalone script to run and inspect the behaviour:

import os
import arcpy

featureClass = r'C:\DATA\Test-Attach\152287.gdb\Markanordningslinje'
objectIds = [5035, 5038]
attachmentFilePath = r'C:\DATA\Attach-Demo\files\ceiling-cat.jpg'

def dumpTable(table, fields):
    print('Dump of match table:')
    with arcpy.da.SearchCursor(table, fields) as cursor:
        for row in cursor:
            print(row)
    return

def fillMatchTable(matchTable, fields, filePath):
    with arcpy.da.InsertCursor(matchTable, fields) as cursor:
        for oid in objectIds:
            values = (oid, filePath)
            print('Inserting into matchTable: %d, %s' % values)
            cursor.insertRow(values)
    return

def main():

    # Build in memory mapping table with fields:
    # ID : object ID
    # FILEPATH : path to file
    matchTableName = 'my_matchtable'
    matchTablePath = r'in_memory\%s' % matchTableName
    arcpy.Delete_management(matchTablePath) # just in case...
    matchTable = arcpy.CreateTable_management('in_memory', matchTableName)
    arcpy.AddField_management(matchTable, "ID", "LONG", 9)
    arcpy.AddField_management(matchTable, "FILEPATH", "TEXT", 500)
    fields = ["ID", "FILEPATH"]

    oidFieldName = arcpy.Describe(featureClass).OIDFieldName

    # Remove existing attachments with the same name to avoid duplication if the tool is ran several times
    # Use only finamename.ext, because file name is stored without path in featureclass__ATTACH table
    print('Removing existing attachments')
    fillMatchTable(matchTable, fields, os.path.basename(attachmentFilePath))
    dumpTable(matchTable, fields)
    arcpy.RemoveAttachments_management(featureClass, oidFieldName, matchTable, "ID", "FILEPATH")
    arcpy.DeleteRows_management(matchTablePath) # clean all rows

    # Now add attachments
    print('Adding new attachments')
    fillMatchTable(matchTable, fields, attachmentFilePath)
    dumpTable(matchTable, fields)
    arcpy.AddAttachments_management(featureClass, oidFieldName, matchTable, "ID", "FILEPATH")

    # Delete in-memory match table
    arcpy.Delete_management(matchTablePath)

    return

if __name__ == '__main__':
    main()
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

And here are contents of Markanordningslinje__ATTACH before and after script run. As you see object with ID 5038 had 2 ceiling-cat.jpg attachments with IDs 11 and 12 but RemoveAttachments_management only removed attachment ID 11 and ID 12 was left unchanged.RemoveAttachments_management doesn

Did I miss something here? I expected both attacments with IDs 11 and 12 to be deleted.

Tags (1)
0 Kudos
1 Reply
RemigijusPankevičius
New Contributor III

Script output, everything as expected:

Removing existing attachments
Inserting into matchTable: 5035, ceiling-cat.jpg
Inserting into matchTable: 5038, ceiling-cat.jpg
Dump of match table:
(5035, u'ceiling-cat.jpg')
(5038, u'ceiling-cat.jpg')
Adding new attachments
Inserting into matchTable: 5035, C:\DATA\Attach-Demo\files\ceiling-cat.jpg
Inserting into matchTable: 5038, C:\DATA\Attach-Demo\files\ceiling-cat.jpg
Dump of match table:
(5035, u'C:\\DATA\\Attach-Demo\\files\\ceiling-cat.jpg')
(5038, u'C:\\DATA\\Attach-Demo\\files\\ceiling-cat.jpg')

0 Kudos