I have 2 migrate classes - ProductsNewMigrate and ProductsUpdateMigrate.

1) ProductsNewMigrate runs initially, adding products from a CSV file into Drupal. I can confirm this works correctly, the new products are created and a migrate map is set up in the database.

2) ProductsUpdateMigrate is required to import another CSV (exactly the same structure as in 1.) but with the updated product data originally migrated via ProductsNewMigrate.

I just can't get the Update migrate to work.
I receive the error: array_flip(): Can only flip STRING and INTEGER values

When looking at the migrate map table for this Migration - migrate_map_productsupdate.. I notice sourceid1 is set to the SKU - which is correct. However, destid1 and destid2 (product_id and product_revision respectively) are both null values - which could be causing this?

Edit: Also receive the warning message: "product_id" was used as destination field in "sku" mapping but is not in list of destination fields when viewing the migrate page!

See the code below:


class ProductsUpdateMigration extends CustomMigration {
  public function __construct() {
    $this->description = t('Import new products from CSV');

    $csvfile = "/drupal/products_updated.csv";
    $columns = array(
      0 => array('sku', 'Product SKU'),
      1 => array('title', 'Product title'),
      2 => array('colour_specific', 'Product colour specific'),
      3 => array('price_group', 'Price Group'),
      4 => array('composition', 'Product Composition'),
      5 => array('width', 'Width'),
      8 => array('price', 'Product Price'),

    $this->map = new MigrateSQLMap($this->machineName,
        'sku' => array(
          'type' => 'varchar',
          'length' => 255,
          'not null' => TRUE,
          'description' => 'SKU/newref',
          'alias' => 'p',
    $this->source = new MigrateSourceCSV($csvfile, $columns, array('header_rows' => 1));
    $this->destination = new MigrateDestinationEntityAPI('commerce_product', 'blinds');
    $this->systemOfRecord = Migration::DESTINATION;

    // print_r($this);

    // Mapped fields
    $this->addFieldMapping('product_id', 'sku')
    $this->addFieldMapping('title', 'title');
    $this->addFieldMapping('field_blinds_colour_specific', 'colour_specific');
    $this->addFieldMapping('field_blinds_composition', 'composition');
    $this->addFieldMapping('field_blinds_width', 'width');
    $this->addFieldMapping('commerce_price', 'price');
    $this->addFieldMapping('field_blinds_price_group', 'price_group');

  public function prepareRow($current_row) {
    $colours = explode(';', $current_row->colour_specific);
    // // print '<pre>';
    // // print_r($colours);
    // // print '</pre>';
    $current_row->colour_specific = $colours;
    // $current_row->migrate_map_destid1 = 62;
    // $current_row->migrate_map_destid2 = 67;
    return TRUE;

  public function prepare($entity, stdClass $row) {
  • Just saying: Normally you should only have one migration, which automatically decides whether to create a new entity or update an existing entity.
    – donquixote
    Commented Jul 13, 2016 at 12:05

1 Answer 1


Took a slightly different approach to solve this.

  1. Upgraded Migrate module from version 2.5 to 2.6
  2. Ran upgrades drush updatedb, made sure the migration groups were registered (did this via migrate ui)
  3. After reading the following articles regarding the new 'trackchanges' hash value option: http://timonweb.com/using-hash-value-trackchanges-to-detect-source-data-changes-in-migrate-for-drupal-7 & http://www.acquia.com/blog/migrate-26-framework-changes I now applied the following to the migrate in step 1):

    $this->source = new MigrateSourceCSV($csvfile, $columns, array(
      'header_rows' => 1,
      'track_changes' => 1

The use of track changes now allows the same CSV to be uploaded, any new rows will create a product. Any changes will be detected via the hash that this option provides in the migrate_map table - thus causing the particular product to be updated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.