Migration bringing in duplicate taxonomy terms I have a very simple taxonomy term migration (migrate module, that lets in duplicate terms for no reason I can figure out.  I have tried explicitly setting allow_duplicates to False, even though that should be the default behavior, but nothing changes.  The base migration that this migration inherits from just sets up a db connection object, sets up team description variables, and sets some configuration variables.  It also sets up a few helper methods that are not used in this migration. 

Here is the migration class:

class EnviroscopeKeywordMigration extends BaseEnviroscopeMigration
{
    public function __construct($arguments)
    {
        parent::__construct($arguments);

        $this-&gt;description = t('import Keyword data');
        $query = $this-&gt;getConnection()
            -&gt;select('doc_keyword', 'k')
            -&gt;fields('k', array('ID', 'NAME'));

        $this-&gt;dependencies = array("GeoArea");

        $this-&gt;source = new MigrateSourceSQL($query, array(), NULL, array('map_joinable' =&gt; FALSE));

        $this-&gt;destination = new MigrateDestinationTerm('keywords');
        $this-&gt;map = new MigrateSQLMap($this-&gt;machineName,
            array(
                'ID' =&gt; array(
                    'type' =&gt; 'int',
                    'length' =&gt; 11,
                    'not null' =&gt; TRUE,
                    'description' =&gt; 'Keyword ID',
                ),
            ),
            MigrateDestinationTerm::getKeySchema()
        );

        $this-&gt;addFieldMapping('name', 'NAME');

        $this-&gt;addUnmigratedDestinations(array(
            'description',
            'parent',
            'parent_name',
            'format',
            'weight',
            'path',
            'pathauto',
        ));
    }

}


Can somebody, PLEASE help me debug why this might be bringing in duplicate terms like this:
I ended up biting the bullet and writing it myself.  I still don't know what was causing it to not work in the first place, but I replicated the desired behavior with this helper method in the migration class:

public function check_for_existing_term($taxonomy, $term) {
    $query = db_select('taxonomy_vocabulary', 'v')
        -&gt;condition('machine_name', $taxonomy);
    $query-&gt;innerJoin('taxonomy_term_data', 'td', 'v.vid=td.vid');
    $new_tid = $query-&gt;fields('td', array('tid'))
        -&gt;condition('td.name', $term)
        -&gt;execute()
        -&gt;fetchField();
    return ($new_tid) ? $new_tid : False;
}


In the constructor of the migration class I set $this-&gt;taxonomy = 'keywords'; and I used that in $this-&gt;destination = new MigrateDestinationTerm($this-&gt;taxonomy);, then I added the following prepareRow:

    public function prepareRow($row)
    {
        $new_tid = $this-&gt;check_for_existing_term($this-&gt;taxonomy, $row-&gt;NAME);
        if ($new_tid) {
            $this-&gt;map-&gt;saveIDMapping($row, array($new_tid),
                MigrateMap::STATUS_IGNORED, MigrateMap::ROLLBACK_DELETE);
            $this-&gt;rollbackAction = MigrateMap::ROLLBACK_DELETE;
            return FALSE;
        } else {
            return TRUE;
        }
    }


This tries to find a matching term in the database for each row.  If it finds it, it adds an entry in the map table and then returns FALSE so the migration won't do anything further for that row.  If it is a new term it returns True, and the migration continue happily, adding in the new term.