2

I have Drupal 8 site I need to migrate a bunch of data into from a different CMS. What I'd like to do is write a basic SQL query and iterate through the results, creating a new node for each returned row.

Since it's a one time thing - do I need to write a full module for this - or can I just hook into drupal some other way (like through the main index.php file) and do the node::create([]) $node->save() stuff from within there?

Never done something like this before - and looking for the easiest way. Any help/guidance is appreciated!

1

3 Answers 3

0

You don't need a "full" module for this, you can do this with two files and a few lines of code:

modules/myimport/myimport.info.yml:

name: myimport
description: 'My import module'
core: 8.x
version: 8.x-1.x-dev
type: module

modules/myimport/myimport.module:

<?php
use Drupal\node\Entity\Node;
function import_stuff() {
  // fetch data
  foreach ( $data as $row ) {
    $node = node::create([]);
    $node->save();
  }
}

You can start the import from anywhere in drupal or from the command line with drush:

drush ev 'import_stuff()'
0
0

Your options are:

  1. Feeds module - You can check the doc here.
  2. Export the content from source into csv or json. On the target (D8) either you can use Migrate module to handle the migration but requires custom coding.
  3. Create a json endpoint that will expose the content and in your target (D8) server consume that endpoint. You can then get the content by using Guzzle.

Example...

$request = Drupal::httpClient()->get($url);

See this page for more info.

P.S: I have no experience building with D8 yet but my suggestions above I guess is still applicable.

0

If it's a bunch of data, it's probably best to use the migrate module.

I've recently a migration with migrate_plus, which comes with a migrate_example module you can copy. There's a yml file and a class for BeerNode that you can pretty much copy.

Then, set up your other database in settings.php:

$databases['example_other_db']['default'] = array (
  'database' => 'lifecenter',
  'username' => 'root',
  'password' => 'root',
  'prefix' => '',
  'host' => 'localhost',
  'port' => '',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver' => 'mysql',
);

Then, you can specify the source in the yml file for your importer.

  source:
    key: example_other_db

Then you basically map the fields to custom keys within your migrate class (see BeerNode.php in migrate_example module)

Here's some examples from my recent migration:

  field_copyright_year: copyright
  field_isbn: ISBN
  field_volume: volume
  field_pages_length: pagesLength
  field_pub_title: bookJournalMagazineTitle
  field_edition: edition
  field_short_place: placePublished
  field_shelf_code: callNumber

If you need something complex like an address field you can build it in your class, so the custom key is an array that matches what addressfield expects. There's a prepareRow function where you can do other queries

  /**
   * {@inheritdoc}
   */
  public function prepareRow(Row $row) {

    $row->setSourceProperty('companyName', $this->cleanString($row->getSourceProperty('companyName')));

    $address = [
      "langcode" => "EN",
      "country_code" => "US",
      "administrative_area" => "US-" . $row->getSourceProperty('state'),
      "locality" => $row->getSourceProperty('city'),
      "dependent_locality" => NULL,
      "postal_code" => $this->cleanString($row->getSourceProperty('zip')),
      "sorting_code" => NULL,
      "address_line1" => $row->getSourceProperty('address1'),
      "address_line2" => $row->getSourceProperty('address2'),
      "organization" => $row->getSourceProperty('companyName'),
    ];

    $row->setSourceProperty('address', $address);

    return parent::prepareRow($row);
  }

Then you run the migration from the command line.

1) run "drush ms" and make sure it lists your migration

2) run "drush mi example_migrate_machinename"

3) to pause import, do "drush mst example_migrate_machinename"

4) for other commands you can run " drush | grep migrate"

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.