开发者

migrating node references

I am working on a project to migrate a website from asp.net to drupal architecture. But the site content is very hierarchal and has a lot of references between entities.

for example: each content belongs to a category, and each category belongs to another category section. Now there may be another level of hierarchy even.

I am planning to make use of migrate module for migrating the database content and linking the migrated nodes via a开发者_Go百科 node reference field.

But i am getting stuck with migrate module as i can't find a way to migrate the node reference field anywhere...

can anyone help me out with this...


Actually, it doesnt seem to be that hard .. in 2012. Yes, you have to keep track of source IDs versus import IDs, but the migrate module does this for you, in a neat little table. You can join that table in your source query, and update the node reference field with the nid of the .. referenced node. Ofcourse, the referenced nodes should have already been imported. If they werent, you can run an run an 'update' later and referenced nids get entered based on the latter imports too. In practice:

$query = Database::getConnection(
    'default', 'mysourcedb'
)->select(
    'mysourcetable','source'
)->fields('source', array(
        'id',
        'title',
        'whatever'
        'rel_rec_id'
    )
);

$query->leftJoin('migrate_map_relimport','relmap','relmap.sourceid1=source.rel_rec_id');
$query->addField('relmap','destid1','rel_node_id');

The code above assumes you have a 'mysourcedb' with a 'mysourcetable' in it that refers to a 'rel_rec_id', and theres another import called RelImport that imports the rel table that rel_rec_id is refering to; it should have already run (or will run before you run an additional update). Do a migrate-status once you have the RelImport class to make sure the table exists.

To be able to make joins to the 'migrate_map_relimport' table, make sure map tables are written to the source database, not the drupal database. This is not always necessary, but here it is:

$this->map = new MigrateSQLMap(
    $this->machineName,
        array(
            'id' => array(
                'type' => 'int',
                'unsigned' => true,
                'not null' => true,
                'alias' => 'source' 
              )
        ),
        MigrateDestinationNode::getKeySchema(),
        'mysourcedb' // connection to use to write map tables
);

and finally, assign the retrieved rel_node_id to your node reference:

$this->addFieldMapping( 'field_rel_node', 'rel_node_id' );

Yay, it is rocket science .. YMMV


As far as I know, you will not be able to do this entirely within the migrate module. You'll have to run a few queries directly in MySQL.

Essentially, you'll have to create an extra field in each content type to house their legacy ID's and an additional field for each legacy reference (in addition to the actual nodereference field). Load all the data into the content types (leave the nodereference field empty). Then once all of the entities are loaded in, you run mysql queries to populate the nodereference fields based on the legacy IDs and legacy reference fields. Once that's done you can safely delete these legacy fields.

Not the most elegant solution, but I've used it many times.

Caveats:

  • This is for Drupal 6; Drupal 7's fields implementation is totally different AFAIK.
  • For very large migrations, you might want to do your legacy field deletions through MySQL.


You might also take a look at the code for the Content Migrate module (more information at https://drupal.org/node/1144136). It's for migrating D6 Content Construction Kit (CCK) content to D7 Fields and it's been integrated with the References module.

It won't do what you need out of the box, as you're coming from an ASP.net site instead of a D6 site, but it may provide some clues.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜