Domanda

Devo apportare modifiche a un database di produzione in uso. Aggiungo solo alcune colonne. Ho apportato le modifiche al database degli sviluppatori con le migrazioni. Qual è il modo migliore per aggiornare il database di produzione preservando i dati esistenti e senza interrompere troppo l'operazione?

È MYSQL e avrò bisogno di aggiungere dati alle colonne anche per i record già esistenti. Una colonna può avere un valore predefinito (è booleano) ma l'altra è un timestamp e dovrebbe avere un valore retrodatato arbitrario. I conteggi delle righe non sono enormi.

Quindi, se uso le migrazioni come faccio ad aggiungere dati e come ottengo che facciano solo le due (o tre - aggiungo le migrazioni più recenti sul db di produzione quando non è stato inizialmente creato tramite le migrazioni (credo hanno usato lo schema invece)?

È stato utile?

Soluzione

Sembra che tu sia in uno stato in cui lo schema db di produzione non corrisponde esattamente a quello che stai usando in dev (anche se non è del tutto chiaro). Vorrei tracciare una linea nella sabbia e ottenere quel prodotto in uno stato migliore. In sostanza, quello che vuoi fare è assicurarti che il db del prodotto abbia un & Quot; schema_info & Quot; tabella che elenca tutte le migrazioni che > non < mai voluto correre in produzione. Quindi puoi aggiungere migrazioni al contenuto del tuo cuore e funzioneranno contro il db di produzione.

Una volta fatto che puoi scrivere le migrazioni che aggiungono modifiche allo schema o aggiungono dati, ma una cosa di cui devi fare molta attenzione è che se aggiungi dati usando una migrazione, devi definire il modello all'interno della migrazione stessa , in questo modo:

class AddSomeColumnsToUserTable < ActiveRecord::Migration
  class User < ActiveRecord::Base; end
  def self.up
    add_column :users, :super_cool, :boolean, :default => :false
    u = User.find_by_login('cameron')
    u.super_cool = true
    u.save
  end

  def self.down
    remove_column :users, :super_cool
  end
end

La ragione di ciò è che in futuro potresti rimuovere del tutto il modello, durante un refactoring o altro. Se non si definisce la classe utente sulla riga & Quot; User.find_by_login ... & Quot; la migrazione genererà un'eccezione che è un grande dolore.

Altri suggerimenti

Seguo sempre questa procedura:

  • Scarica il database dei prod con il comando mysqldump
  • Popolare il database dev / test con dump usando il comando mysql
  • Esegui migrazioni in sviluppo / test
  • Controlla la migrazione ha funzionato
  • Scarica il database prod con il comando mysqldump (come potrebbe essere cambiato) mantenendo il backup sul server
  • Esegui migrazioni su prod (usando capristano)
  • La migrazione di test ha funzionato su prod
  • Bevi birra (mentre guardi i log degli errori)

C'è un motivo per cui non stai usando le stesse migrazioni che hai usato nel tuo ambiente di sviluppo?

L'aggiunta di una colonna con add_column in una migrazione dovrebbe essere non distruttiva: genererà un " ALTER TABLE " dichiarazione. Se sai cosa inserirai nelle colonne una volta create, puoi inserire i valori all'interno della migrazione (puoi scegliere un'alternativa meno dispendiosa in termini di tempo se i conteggi delle righe sono grandi).

La rimozione o l'alterazione della definizione di una colonna è, credo, dipendente dalla piattaforma: alcuni consentiranno la cancellazione di una colonna in atto, altri eseguiranno una sequenza di comandi rename-create-select-drop.

Per essere più specifici, abbiamo bisogno di maggiori informazioni: che tipo di migrazione stai guardando, su quale piattaforma stai eseguendo, devi impostare i valori come parte della migrazione? Cose del genere sarebbero di grande aiuto: basta modificare la domanda, che la farà risalire all'elenco.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top