2015-10-27 24 views
12

Attualmente la mia app utilizza il metodo Sequelize sync() per creare il database e io voglio cambiarlo per utilizzare il sistema di migrazione.Associazioni in Sequenza delle migrazioni

Uno dei miei modelli ha associazioni belongsTo() con altri modelli e non so davvero come creare il codice di migrazione iniziale per queste associazioni.

Devo creare manualmente la chiave esterna con query SQL oppure sono disponibili alcuni metodi?

+0

Si desidera utilizzare le migrazioni per creare la struttura iniziale del database o si desidera aggiornare la struttura del database corrente utilizzando le migrazioni? – ezpn

+0

Voglio creare la struttura iniziale del database prima – loics2

risposta

11

Caso 1: l'inizializzazione del database

Se il vostro scopo è quello di aggiungere le relazioni durante l'inizializzazione della struttura del database è meglio utilizzare solo sync metodo invece di aggiungere manualmente utilizzando le migrazioni. Se i tuoi modelli sono progettati correttamente e hanno relazioni definite, verranno creati automaticamente durante l'esecuzione del metodo sync.

Dai uno sguardo allo sequelize express example. In elenco modelli avete tre file:

  • index.js - che comprende tutti i modelli
  • task.js - compito modello
  • user.js - utente modello

Guardate task.js contenuti, a partire dalla linea 7 della il seguente codice crea una relazione tra i modelli Utente e Attività:

classMethods: { 
    associate: function(models) { 
    Task.belongsTo(models.User, { 
     onDelete: "CASCADE", 
     foreignKey: { 
     allowNull: false 
     } 
    }); 
    } 
} 

Se si preparano correttamente le relazioni nei file di modello, la sincronizzazione creerà le chiavi esterne per l'utente. Le migrazioni non sono necessarie in questo caso.

Vi incoraggio a leggere l'intero esempio espresso readme.md e a sfogliare i file del repository per vedere come funzionano le cose con express e sequelize.

Caso 2: migrazione Struttura del database

Nel caso in cui si dispone già di alcuni dati che si desidera conservare, è necessario utilizzare script di migrazione, perché l'unico modo per la sincronizzazione di ristrutturare il database è di distruggerla completamente a fianco di tutti i suoi dati.

È possibile leggere informazioni di base su migrations in the sequelize docs. Sfortunatamente i documenti non coprono la creazione di una relazione. Supponiamo che tu voglia creare la seguente relazione: l'utente appartiene al gruppo. Per creare una colonna sul lato utente della relazione, è possibile utilizzare il metodo addColumn.

queryInterface.addColumn(
    'user', 
    'group_id', 
    { 
    type: Sequelize.INTEGER, 
    allowNull: true 
    } 
) 

Purtroppo non c'è una bella funzione (ancora) per creare il vincolo di chiave esterna per voi, ma è possibile farlo manualmente utilizzando il metodo di query sequelize. Esempio PostgreSQL:

queryInterface.sequelize.query("ALTER TABLE user 
    ADD CONSTRAINT user_group_id_fkey FOREIGN KEY (group_id) 
    REFERENCES group (id) MATCH SIMPLE 
    ON UPDATE CASCADE ON DELETE CASCADE;"); 

Edit: Aggiunto caso di migrazione struttura del database

+0

Hmm ok grazie. Penso di essere un po 'confuso riguardo le differenze tra le migrazioni e la sincronizzazione e quando usarle. Quindi, se aggiornassi i miei modelli usando solo sync(), migrerebbe correttamente il mio database? – loics2

+2

Sync crea una struttura di database pulita in base ai modelli correnti. Se l'attributo force è impostato su false, creerà solo il database se non esiste già. Altrimenti cancellerà l'intero database ogni volta che riavvierai il server. Gli script di migrazione vengono utilizzati per modificare il database esistente operando su strutture e dati già esistenti. È utile nell'ambiente di produzione in cui si desidera mantenere i dati tra gli aggiornamenti. – ezpn

+0

Giù al voto perché la domanda riguarda specificamente le migrazioni (di cui hai bisogno per la produzione) e questa risposta non risponde. (Ma buona risposta per "sincronizzazione"). – AJP

2

Dopo un sacco di ricerche, ho trovato un paio di post di blog che spiegano quello che volevo fare.

Apparentemente non è davvero il modo comune per farlo, ma mi sembra più logico. Se si desidera utilizzare solo le migrazioni, è necessario utilizzare query SQL per creare la migrazione iniziale.

Ecco i post: the first one, ispirato allo this one.

Ma comunque, penso che l'ezrepotein abbia ragione nel creare il database iniziale con sincronizzazione, e quindi migrare. Sembra più semplice dell'uso di umzug e usa solo le migrazioni.

+0

Sono d'accordo con tutto fino all'ultima frase. Hai bisogno di migrazioni per il codice di produzione. – AJP

+0

Potresti approfondire il possibile caso d'uso per utilizzare le migrazioni per inizializzare il database sulla produzione? – ezpn

+1

@ezrepotein sync va bene per la creazione di db ovviamente solo il titolo della domanda è formulato nelle più generali (e quindi utili) "associazioni in sequelize migrations". In realtà preferisco usare le migrazioni in produzione, perché no se lo fai anche per il tuo test db. Quindi il tuo db setup e update usano lo stesso comando dichiarativo come 'sequelize db: migrate', invece di alcuni' se no db, quindi db: sync, altrimenti db: migrate' kinda thing. Penso che ci sia una preferenza secondaria generalmente accettata per il primo rispetto a quella successiva. – AJP

0

è possibile aggiungere riferimenti alle migrazioni

Exmaple:

user_id: { 
    type: Sequelize.BIGINT, 
    references: { 
     model: "users", 
     key: "id" 
    } 
}, 

Basta assicurarsi che il modello si fa riferimento esiste.

0

Aggiungendo questo come risposta invece di un commento (non abbastanza rep) per la risposta @ aryeh-armon sopra. È il nome della tabella che devi accertarti che esista piuttosto che il nome del modello. Ad esempio, se il tuo modello è denominato Job e la tua tabella di db è nominata Jobs, la migrazione sembrerebbe invece questa.

jobId: { 
type: Sequelize.INTEGER, 
references: { 
    model: "Jobs", 
    key: "id" 
    } 
}, 
+0

E 'un chiarimento sulla risposta di aryeh armon (che, sono d'accordo, dovrebbe essere un commento) ma non ho abbastanza rep per commentare ancora le risposte di altri utenti. – adamS

Problemi correlati