2014-12-05 2 views
5

Я высева мой дб из массива, который выглядит следующим образом (слова и определения в отношения многие ко многим):Knex миграция высева завершается ошибки внешнего ключа

var seeds = [ 
{ 
    "word": "Click", 
    "definitions": ["Computer", "Mouse", "Tasto", "Pulsante", "Selezionare"] 
}, { 
    "word": "Galoppo", 
    "definitions": ["Cavallo", "Andatura", "Trotto", "Ippica", "Passo"] 
}, { 
    "word": "Raggio", 
    "definitions": ["Sole", "Bicicletta", "Diametro", "Luce", "Laser"] 
}, { 
. 
. 
.goes on for 1089 objects 

Это то, что я пробовал:

exports.seed = function (knex, Promise) { 
var promises = seeds.map(function (seed) { 
    return knex('words').insert({ 
     word: seed.word 
    }, 'id').then(function (word_id) { 
     var promises = seed.definitions.map(function (definition) { 
      return knex('definitions').insert({ 
       definition: definition 
      }, 'id').catch(function (err) { 
       if (err.code === 1062) 
        return knex('definitions').select('id').where({ 
         definition: definition 
        }).then(function (duplicate) { 
         return knex('definitions_words').insert({ 
          definition_id: duplicate[0].id, 
          word_id: word_id 
         }); 
        }); 
      }).then(function (definition_id) { 
       return knex('definitions_words').insert({ 
        definition_id: definition_id, 
        word_id: word_id 
       }); 
      }); 
     }); 
     return Promise.all(promises); 
    }); 
}); 
return Promise.all(promises); 
}; 

Слова уникальны в своих семенах, но определения могут повторяться, так я ловлю ошибку дублирования и захватить идентификатор дубликата положить, что в таблице соединения. Это, кажется, работает хорошо, таблица стык фактически заканчивается 1089 * 5 строк (5445), но я получаю сообщение об ошибке на кли:

Error: Cannot add or update a child row: a foreign key constraint fails 
(`mytable`.`definitions_words`, 
CONSTRAINT `definitions_words_definition_id_foreign` 
FOREIGN KEY (`definition_id`) REFERENCES `definitions` (`id`)) 

ответ

0

Хотя мы не можем видеть ваши миграции (и это довольно старый вопрос), что обычно происходит с этими ограничениями внешнего ключа, состоит в том, что вы определили definition_id в words для ссылки definitions.id. По этой причине вы не можете создать word до definition.

Без тестирования и засвидетельствовал из проверки ошибок, я предположил бы, что вам использовать что-то больше, как это:

exports.seed = function (knex, Promise) { 
    var promises = seeds.map(function (seed) { 
    // Check for an existing definition. More recently 
    // you can use `whereNotExists` but you always need 
    // an id here whatever the case 
    return knex('definitions') 
     .select('id') 
     .where('definition', seed.definition) 
     .then(function (definition_id) { 
     if (definition_id.length === 1) return definition_id[0] 
     return knex('definitions') 
      .insert({ definition: definition }) 
     }) 
     .then(function (definition_id) { 
     // Use the definition once it exists 
     return knex('words') 
      .insert({ word: seed.word, definition_id: definition_id }) 
      .then(function (word_id) { 
      return { word_id: word_id, definition_id: definition_id } 
      }); 
     }) 
     .then(function (join_ids) { 
     // Finally, update the join table 
     return knex('definitions_words') 
      .insert({ 
      definition_id: join_ids.definition_id, 
      word_id: join_ids.word_id 
      }) 
     }) 

    return Promise.all(promises); 
}; 
Смежные вопросы