I'm writing a migrator for a now-unsupported WordPress plugin that used a single "attachments" table to store data ranging from thumbnails to musical genres. It looks like this:

mysql> describe attachment;
| Field                | Type         | Null | Key | Default | Extra          |
| attachment_id        | mediumint(7) | NO   | PRI | NULL    | auto_increment |
| attachment_target    | varchar(32)  | YES  |     | NULL    |                |
| attachment_target_id | mediumint(7) | YES  |     | 0       |                |
| attachment_type      | varchar(32)  | YES  |     | NULL    |                |
| attachment_info      | text         | YES  |     | NULL    |                |
6 rows in set (0.00 sec)

attachment_id is just an ID, attachment_target_id will correspond to a NID from the "artist" content type I'm trying to import this into, attachment_type is either "genre" or "thumbnail" and attachment_info is the actual data contained in the row ("Disco", as an example for a genre.).

To import all the genres into a taxonomy field, it seems I would extend the class that imports all the artists from the other table, then using $this->systemOfRecord = Migration::DESTINATION, import each row into the existing nodes. Alas, given each row would be a new migration item, it seems this would overwrite the values.

I've also thought about adding a sub-query to my initial artist migration that returns a comma-separated list of genres; alas, I'm not sure how I'd do that with Drupal database abstraction layer.

Any help? Thanks!

  • 1
    just do 2 migrations. Create a copy of your taxonomy terms in D7 with some php code. Then 1) move artists 2) go thru second table with a simple migration query and assign the correct ID of your existing D7 terms. you can try the approaches you've mentioned -- they seem more complicated.
    – tenken
    Commented Apr 2, 2013 at 17:31
  • @tenken -- So, migrate the genres first, you're saying? That's an idea...
    – aendra
    Commented Apr 2, 2013 at 17:41
  • 2
    Don't get so complex. The only time you should use a dynamic query is when you have to customize the query terms based on the use case. Over 90% of the queries run in drupal are static queries using $result = db_query(). Then iterate through the rows to create an array: $artist[$target][$type][] = $info. Then implode(',', $artist[$target]['genre']) will give you your comma separated list.
    – Triskelion
    Commented Apr 2, 2013 at 17:55
  • @Triskelion Wait, you mean, just make a separate query inside of the class, using maybe prepareRow? That's an idea too... Thanks!
    – aendra
    Commented Apr 2, 2013 at 19:01
  • @Triskelion -- I've replaced my dynamic query with a nice static query that does everything I need it to, however, now I get the following error: "Recoverable fatal error: Argument 1 passed to MigrateSourceSQL::__construct() must implement interface SelectQueryInterface, instance of DatabaseConnection_mysql given, called in x/sites/all/modules/wordtour/wordtour.migrate.inc on line 116 and defined in MigrateSourceSQL->__construct() (line 108 of x/sites/all/modules/migrate/plugins/sources/sql.inc)"?
    – aendra
    Commented Apr 2, 2013 at 19:35

1 Answer 1


The piece I was missing was GROUP_CONCAT for the attachment table. My query now looks like this:

$query = Database::getConnection('default', 'wp')
       ->select('artists', 'a');
$query->join('attachment', 'at', 'a.artist_id = at.attachment_target_id');
//Pull in genres.
$query->addExpression('GROUP_CONCAT(DISTINCT at.attachment_info)', 'genres'); 
$query->condition('at.attachment_target', 'artist');
$query->condition('at.attachment_type', 'genre');

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.