The problem

After creating a migration for a client, when deploying to their server, the migration fails due to the queries generated by Migrate tries to create the nodes with vid = 0.

% drush mi KDBEventFeedImport 
Duplicate entry '0' for key 'vid'
query: INSERT INTO node (vid, type, language, title, uid, status, created, changed, comment, promote, moderate, sticky, tnid, translate) VALUES (0, 'event', 'da', 'Valby Kino for børn: Lillebror og Knorten ', 0, 1, 1326277413, 1336123513, 2, 1, 0, 0, 0, 0)Column 'nid' cannot be null
query: UPDATE content_type_event SET vid = 0, nid = NULL, field_datetime_value = '2012-05-05 11:00:00', field_datetime_value2 = NULL, field_entry_price_value = NULL WHERE vid = 0Column 'nid' cannot be null
query: UPDATE content_field_library_ref SET vid = 0, nid = NULL, field_library_ref_nid = NULL WHERE vid = 0Column 'nid' cannot be null
query: UPDATE content_field_tema_ref SET vid = 0, nid = NULL, field_tema_ref_nid = NULL WHERE vid = 0Column 'nid' cannot be null
query: UPDATE content_field_teaser SET vid = 0, nid = NULL, field_teaser_value = NULL WHERE vid = 0Column 'nid' cannot be null
query: UPDATE content_field_list_image SET vid = 0, nid = NULL, field_list_image_fid = NULL, field_list_image_list = NULL, field_list_image_data = NULL WHERE vid = 0Duplicate entry '0-0' for key 'PRIMARY'
query: INSERT INTO content_field_content_images (vid, nid, delta, field_content_images_fid, field_content_images_list, field_content_images_data) VALUES (0, 0, 0, NULL, NULL, NULL)Duplicate entry '0-0' for key 'PRIMARY'
query: INSERT INTO content_field_file_attachments (vid, nid, delta, field_file_attachments_fid, field_file_attachments_list, field_file_attachments_data) VALUES (0, 0, 0, NULL, NULL, NULL)Duplicate entry '0-0' for key 'PRIMARY'
query: INSERT INTO content_field_ting_refs (vid, nid, delta, field_ting_refs_ting_object_id, field_ting_refs_ting_ref_type, field_ting_refs_description) VALUES (0, 0, 0, NULL, NULL, NULL)New object was not saved, no error provided                                                                                                                                                                                                                                                                                                                                                                                   [error]
Duplicate entry '0' for key 'vid'
query: INSERT INTO node (vid, type, language, title, uid, status, created, changed, comment, promote, moderate, sticky, tnid, translate) VALUES (0, 'event', 'da', 'VIVA - På tur i Caribien, Caramba', 0, 1, 1326468509, 1336123514, 2, 1, 0, 0, 0, 0)Duplicate entry '0' for key 'PRIMARY'
query: INSERT INTO node_comment_statistics (nid, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count) VALUES (0, 1336123514, NULL, 0, 0)Column 'nid' cannot be null
query: UPDATE content_type_event SET vid = 0, nid = NULL, field_datetime_value = '2012-05-06 15:00:00', field_datetime_value2 = NULL, field_entry_price_value = NULL WHERE vid = 0Column 'nid' cannot be null
query: UPDATE content_field_library_ref SET vid = 0, nid = NULL, field_library_ref_nid = NULL WHERE vid = 0Column 'nid' cannot be null
query: UPDATE content_field_tema_ref SET vid = 0, nid = NULL, field_tema_ref_nid = NULL WHERE vid = 0Column 'nid' cannot be null
query: UPDATE content_field_teaser SET vid = 0, nid = NULL, field_teaser_value = NULL WHERE vid = 0Column 'nid' cannot be null
query: UPDATE content_field_list_image SET vid = 0, nid = NULL, field_list_image_fid = NULL, field_list_image_list = NULL, field_list_image_data = NULL WHERE vid = 0Duplicate entry '0-0' for key 'PRIMARY'
query: INSERT INTO content_field_content_images (vid, nid, delta, field_content_images_fid, field_content_images_list, field_content_images_data) VALUES (0, 0, 0, NULL, NULL, NULL)Duplicate entry '0-0' for key 'PRIMARY'
query: INSERT INTO content_field_file_attachments (vid, nid, delta, field_file_attachments_fid, field_file_attachments_list, field_file_attachments_data) VALUES (0, 0, 0, NULL, NULL, NULL)Duplicate entry '0-0' for key 'PRIMARY'
query: INSERT INTO content_field_ting_refs (vid, nid, delta, field_ting_refs_ting_object_id, field_ting_refs_ting_ref_type, field_ting_refs_description) VALUES (0, 0, 0, NULL, NULL, NULL)New object was not saved, no error provided                                                                                                                                                                                                                                                                                                                                                                                   [error]

[And several screenfuls more of the same]

The code

The migration code is available on Github

The details

  • PHP 5.2.6-1+lenny13
  • MariaDB 5.2.10
  • drush version 4.5
  • Drupal: Pressflow 6.23
  • Migrate 6.x-2.3
  • Autoload 6.x-2.1
  • DBTNG 6.x-1.0-rc4

The plea

Any ideas?

Comments

mikeryan’s picture

Title: Migrate 2.3 tries to create nodes with vid = 0, leading to “Duplicate entry '0' for key 'vid'” errors » Migrate 2.3 tries to create nodes with vid = 0, leading to “Duplicate entry '0' for key 'vid' errors
Assigned: Unassigned » mikeryan
Category: bug » support
Status: Active » Postponed (maintainer needs more info)

Of course, Migrate doesn't generate the queries itself, it calls node_save(). My first thought was that you were mapping 'vid' in your migration, but I don't see that there. I'm having a hard time seeing a code path that could lead to this error - node_save() does:

  if ($node->is_new) {
    _node_save_revision($node, $user->uid);
    drupal_write_record('node', $node);

_node_save_revision() will save a row to the node_revisions table, which should generate a new vid value and set it in $node. Then, drupal_write_record() generates the INSERT query you see. So, if you're not setting the vid, somehow _node_save_revision is setting it to 0. But, if it were doing that repeatedly (as it must for you to get the duplicate key error), we would expect to see duplicate key errors on the node_revision table before it gets to the error on the node table.

My best guess is that somehow the _node_save_revision write to node_revisions is failing, but I'm perplexed why you're not seeing an error there.

Probably unrelated to your problem, but these mappings appear to be backwards:

    $this->addFieldMapping('price', 'field_entry_price');
    $this->addFieldMapping('summary', 'field_teaser');
    $this->addFieldMapping('author', 'name');

The destination field comes first, then the source field.

Also, you could set status, language, and format directly in the mappings using defaultValue(), rather than assigning them in prepare().

mikl’s picture

Status: Postponed (maintainer needs more info) » Active

First of all, thanks for pointing out those mapping mistakes – fixed them, but the problem persists.

I tried insering a debug_traceback in the MySQL error handler, so I could try and pinpoint the actual problem.

It is available here: http://dpaste.de/BwVsn/#l256

It seems that the error happens inside `_node_save_revision` (see line 256) . It seems to be called with a node where nid = int(0). This in turn comes from node_save where nid = 0 is also set. Further down the traceback dives into migration.inc, and I'm not entirely sure of the interpretation. Any ideas?

mikeryan’s picture

Status: Active » Postponed (maintainer needs more info)

This looks more like what I'd expect - in your original report, it was inserting into node that failed, this is failing on node_revisions. So, the question is, how does $node->nid get set to 0? It appears that it's already 0 when MigrateDestinationNode::import() is called, so it seems like it's happening in Migration::applyMappings() - but you've got nothing mapped to 'nid'.

I would try to trace through applyMappings() as it builds the node object and see if you can catch it in the act.

mikeryan’s picture

Status: Postponed (maintainer needs more info) » Closed (cannot reproduce)
mikl’s picture

Status: Closed (cannot reproduce) » Active

Okay, the real problem seems to be that MySQL errors are swallowed somehow when running Migrate. The actual error was our old friend: "Incorrect string value: '\xA0tilr\xC3...' for column 'body' at row 1".

This causes `drupal_write_record()` to fail and return false to `_node_save_revision()`, but that does not check the return value, and `node_save()` continues to try and save a record to the node table, but since a revision was not created, vid is set to 0, triggering the aforementioned error. Sigh.

I have no obvious fix for this. I'll be glad to leave Drupal 6 behind…

mikeryan’s picture

Status: Active » Closed (won't fix)

Yes, I don't see much Migrate can do about it. Drupal 7 is better about throwing exceptions...