When your source query is a union, like
$query1 = db_select('node', 'n')->fields('n', array('nid', 'vid', 'title'));
$query2 = db_select('node', 'n')->fields('n', array('nid', 'vid', 'title'));
$query1->union($query2, "ALL");
$this->source = new MigrateSourceSQL($query1);
You may receive the error message when importing:
SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns
if you have your migration source option map_joinable set to TRUE (i.e., Migrate will join the map table directly to your query). This is because the map table fields get added to the first query in the union, so the number of fields don't match. This is easily worked around by wrapping the union in a subquery:
$query1 = db_select('node', 'n')->fields('n', array('nid', 'vid', 'title'));
$query2 = db_select('node', 'n')->fields('n', array('nid', 'vid', 'title'));
$query1->union($query2, "ALL");
// wraps the 2 unions into 1 subselected table 'x'
$queryx = db_select($query1,'x')->fields('x', array('nid', 'vid', 'title'));
$this->source = new MigrateSourceSQL($queryx);
See #1673226: MigrateSourceSQL breaks when SelectQueryInterface query contains union (and not wrapped in a subquery) for more context. Thanks to arscan for identifying the problem and the work-around.
Comments
Might need to specify fields
You may also need to specify fields in order for the migration to work:
A couple pitfalls