Purger ou recréer une base de données Ruby on Rails

582

J'ai une base de données Ruby on Rails de développeur pleine de données. Je veux tout supprimer et reconstruire la base de données. Je pense utiliser quelque chose comme:

rake db:recreate

Est-ce possible?

Un apprenti
la source
Je suggère de regarder au-delà de la réponse la plus élevée. À mon avis, cela rake db:drop db:create db:schema:loadpourrait être plus approprié que rake db:drop db:create db:migrate(même si je suis prêt à me tromper à ce sujet).
Jason Swett du
2
rake db:drop db:create db:migrate
William Hampshire,
db:drop + db:create + db:migrate == db:migrate:reset. Je recourt habituellement à db:schema:load, lorsque les migrations sont interrompues. J'ai rarement besoin de recréer une base de données, donc la vitesse n'a pas beaucoup d'importance. Aussi, si vous avez des migrations non appliquées db:schema:loadet db:resetque vous ne les appliquerez pas. Je ne sais pas si c'est vraiment un argument.
x-yuri

Réponses:

1074

Je connais deux façons de procéder:

Cela réinitialisera votre base de données et rechargera votre schéma actuel avec tous:

rake db:reset db:migrate

Cela détruira votre base de données, puis la créera, puis migrera votre schéma actuel:

rake db:drop db:create db:migrate

Toutes les données seront perdues dans les deux scénarios.

thenengah
la source
36
Il semble rake db:resetégalement exécuter toutes les migrations (au moins sur Rails 3), ce qui devrait être tout ce qui est nécessaire, non?
plindberg
1
Ou plutôt, il laisse le schéma identique à celui qu'auraient toutes les migrations. Mais les migrations ne sont pas exécutées en soi (donc si vous avez des migrations qui insèrent des données, cela ne se produira pas; pour cela, vous devez vraiment utiliser un fichier db / seeds.rb).
plindberg
1
Je sais que pour Tracks GTD app db: migrate n'a pas fonctionné. J'ai dû faire db: reset lors du passage de Sqlite3 à Postgres.
labyrinthe
11
Vous devrez également exécuter rake db:test:preparepour les tests, sinon vous obtiendrez une erreur comme:Could not find table 'things' (ActiveRecord::StatementInvalid)
s2t2
31
Quelqu'un devrait le préciser rake db:resetet rake db:drop db:create db:migrate faire deux choses complètement différentes . Ce dernier efface toute la base de données de l'application, la recrée, puis passe par chaque migration pour mettre à jour le schéma ( db/schema.rbou db/structure.sql), mais ne la remplit pas de données de départ. Au lieu de cela, le premier est un alias pour rake db:drop db:schema:load db:seed, donc il efface toute la base de données de l'application, mais il ne met pas à jour le schéma , puis se remplit de données de départ. Donc, si vous n'avez rien changé dans vos migrations, la première est plus rapide, la seconde est plus sûre.
Claudio Floreani
157

Sur Rails 4, tout ce dont vous avez besoin est

$ rake db:schema:load

Cela supprimerait l'intégralité du contenu de votre base de données et recréerait le schéma à partir de votre fichier schema.rb, sans avoir à appliquer toutes les migrations une par une.

Eneko Alonso
la source
6
fonctionne également pour les rails 3. utile lorsque vous venez de foirer votre base de données de test et que vous souhaitez la réinitialiser à une version de travail qui correspond à votre dev db
bigpotato
Merci pour cela. Je ne m'en rendais pas compte db:dropet j'étais db:createredondant.
Grant Birchmeier
3
Cela ne met pas à jour le schéma, n'est pas un moyen sûr si vous refactorisez vos migrations.
Claudio Floreani
c'est la meilleure réponse pour moi.
roxdurazo
2
Les migrations de refactorisation @ClaudioFloreani demandent des ennuis. Une fois qu'ils ont couru, ils devraient être laissés seuls, de façon permanente.
nrowegt
45

J'utilise la doublure suivante dans le terminal.

$ rake db:drop && rake db:create && rake db:migrate && rake db:schema:dump && rake db:test:prepare

J'ai mis cela comme un alias de shell et je l'ai nommé remigrate

À présent, vous pouvez facilement "chaîner" les tâches Rails:

$ rake db:drop db:create db:migrate db:schema:dump db:test:prepare # db:test:prepare no longer available since Rails 4.1.0.rc1+
TK.
la source
12
Cela va exécuter toutes vos migrations l'une après l'autre, ce qui n'est pas évolutif et est sujet aux erreurs. De plus, je suis presque sûr que db: migrate met à jour votre schéma.rb, donc votre schéma: dump ne fait rien d'utile.
coreyward
alors comment vider la base de données? en cours de développement ... effacer tout cela.
AnApprentice
3
@AnApprentice Vous pouvez exécuter db:reset, qui est juste un Google (ou consultez les guides ). Mon commentaire n'était pas de déconseiller d'utiliser cela, mais d'éviter d'utiliser db:migratequand ce que vous voulez vraiment db:schema:load.
coreyward
7
Soit dit en passant, @TK, vous n'avez vraiment pas besoin d'exécuter tous ces processus en tant que processus distincts en fonction de l'état de sortie du dernier. Au lieu de cela, il suffit de passer toutes les tâches souhaitées à rake, comme suit: rake db:drop db:create db:schema:load.
coreyward
1
C'est anecdotique, mais je n'ai jamais eu de problème en cours d'exécution db:migrate... alors que db:schema:loadc'est sensible à quelqu'un qui oublie de vérifier schema.rb dans le contrôle de version à côté d'une nouvelle migration.
johncip
37

Mise à jour: dans Rails 5, cette commande sera accessible via cette commande:

rails db:purge db:create db:migrate RAILS_ENV=test


Depuis la dernière version de rails 4.2, vous pouvez désormais exécuter:

rake db:purge 

Source: commit

# desc "Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases."
  task :purge => [:load_config] do
    ActiveRecord::Tasks::DatabaseTasks.purge_current
  end

Il peut être utilisé ensemble comme mentionné ci-dessus:

rake db:purge db:create db:migrate RAILS_ENV=test
Robbie Guilfoyle
la source
Comme @bekicot le dit dans un anglais plus simple db:purge"supprimez toutes les données mais conservez toutes les tables et colonnes"
MCB
@MCB J'avais tort, bien sûr, db:purge ne préserve pas les tables.
Yana Agun Siswanto
29

Selon ce que vous voulez, vous pouvez utiliser…

rake db:create

… Pour construire la base de données à partir de zéro config/database.yml, ou…

rake db:schema:load

… Pour construire la base de données à partir de zéro à partir de votre schema.rbfichier.

coreyward
la source
1
Vous devez d'abord supprimer la base de données… ou vous pouvez simplement supprimer les tables si vous préférez.
coreyward
5
+1 pour la charge de schéma. parfois les migrations sont gâchées, mais le schéma doit être ce qui est conservé intact.
Danny
J'ai lu dans The Rails 3 Way que le chargement du schéma est la voie à suivre, par opposition à l'exécution de toutes les migrations. Je ne me souviens pas exactement de leur raisonnement, mais cela semble logique. Si le résultat final est le même dans les deux cas, il semble plus simple et moins sujet aux erreurs de charger la base de données à partir du schéma que d'exécuter un tas de migrations.
Jason Swett
3
Le raisonnement est que les migrations sont destinées à migrer des données et deviennent de plus en plus fragiles au fil du temps à mesure que vos modèles changent. Vous pouvez (et devez) intégrer des modèles à portée minimale dans vos migrations chaque fois que cela est possible pour vous assurer qu'ils s'exécutent, mais cela ne fonctionne pas bien et est beaucoup moins efficace que la construction de la base de données à partir de ce que l'application sait être le point final . Pourquoi s'appuyer sur les migrations pour créer une base de données qui ressemble à votre schéma alors que vous pouvez simplement construire à partir du plan lui-même?
coreyward
13

Depuis la ligne de commande, exécutez

rake db:migrate:reset
user2747051
la source
c'est le seul moyen qui permet à l'application d'exécuter à nouveau toutes les migrations. Parce que chaque migration apporte des modifications à schema.rbet si vous seulement dropet create, migratene fera rien (testé sur les rails 6)
shampooing
12

Utilisez comme

rake db:drop db:create db:migrate db:seed

Tout en une seule ligne. C'est plus rapide car l'environnement n'est pas rechargé encore et encore.

db: drop - supprimera la base de données.

db: create - créera une base de données (host / db / password sera tiré de config / database.yml)

db: migrate - exécutera les migrations existantes à partir du répertoire (db / migration / .rb) *.

db: seed - exécutera les données de graines possibles à partir du répertoire (db / migration / seed.rb) ..

Je préfère généralement:

rake db:reset

faire tout à la fois.

À votre santé!

Manish Shrivastava
la source
1
J'aime ajouter db: test: préparez-vous à cela, pour faire bonne mesure. Cela dépend, bien sûr, si vous testez ou non.
ctc
db:reset == db:drop + db:schema:load + db:seed,db:migrate:reset == db:drop + db:create + db:migrate
x-yuri
11

Exécutez simplement la séquence des étapes: supprimez la base de données, puis recréez-la à nouveau, migrez les données et, si vous avez des graines, semez la base de données:

rake db:drop db:create db:migrate db:seed

Étant donné que l'environnement par défaut rakeest le développement , si vous voyez l'exception dans les tests de spécification, vous devez recréer db pour l' environnement de test comme suit:

RAILS_ENV=test rake db:drop db:create db:migrate

Dans la plupart des cas, la base de données de test est semée pendant les procédures de test, il db:seedn'est donc pas nécessaire de passer une action de tâche. Sinon, vous devez préparer la base de données:

rake db:test:prepare

ou

RAILS_ENV=test rake db:seed

De plus, pour utiliser la tâche de recréation , vous pouvez ajouter dans Rakefile le code suivant:

namespace :db do
   task :recreate => [ :drop, :create, :migrate ] do
      if ENV[ 'RAILS_ENV' ] !~ /test|cucumber/
         Rake::Task[ 'db:seed' ].invoke
      end
   end
end

Ensuite, lancez:

rake db:recreate
Малъ Скрылевъ
la source
8

Vous pouvez manuellement:

rake db:drop
rake db:create
rake db:migrate

Ou tout simplement rake db:reset, qui exécutera les étapes ci-dessus mais exécutera également votre db/seeds.rbfichier.

Une nuance supplémentaire est celle qui se rake db:resetcharge directement à partir de votre schema.rbfichier au lieu d'exécuter à nouveau tous les fichiers de migration.

Vos données sont emportées dans tous les cas.

Erik Trautman
la source
6

Vous pouvez utiliser cette ligne de commande suivante:

rake db:drop db:create db:migrate db:seed db:test:clone
user1358180
la source
4

Pour supprimer une base de données particulière, vous pouvez le faire sur la console rails:

$rails console
Loading development environment
1.9.3 > ActiveRecord::Migration.drop_table(:<table_name>)
1.9.3 > exit

Et puis migrez à nouveau DB

$bundle exec rake db:migrate 
Kush
la source
4

Sur rails 4.2, pour supprimer toutes les données mais conserver la base de données

$ bin/rake db:purge && bin/rake db:schema:load

https://github.com/rails/rails/blob/4-2-stable/activerecord/CHANGELOG.md

Yana Agun Siswanto
la source
Eh bien ... Je viens de l'essayer, mais cela ne préserve pas les tables et les colonnes. Vous devez exécuter un db: migrate après avoir exécuté un db: purge. Cela ne préserve donc pas les tables et les colonnes. Il conserve cependant la base de données elle-même, vous n'avez donc pas à faire de db: create
Freddo
1
@Cedric Vous avez raison, db: la purge ne préserve pas la table. J'ai mis à jour le code.
Yana Agun Siswanto
3

Vous pouvez utiliser db:reset- pour exécuter db: drop et db: setup ou db:migrate:reset- qui exécute db: drop, db: create et db: migrate.

dépendant à vous voulez utiliser existe schema.rb

Aleksandr Babak
la source
2

Selon le guide Rails , cette doublure devrait être utilisée car elle se chargerait à partir de au schema.rblieu de recharger les fichiers de migration un par un:

rake db:reset
Victor
la source
1

Parce qu'en développement, vous voudrez toujours recréer la base de données, vous pouvez définir une tâche de râteau dans votre dossier lib / tasks comme ça.

  namespace :db do
      task :all => [:environment, :drop, :create, :migrate] do
   end 
end

et dans le terminal, vous exécuterez

rake db:all

il reconstruira votre base de données

Obed Lorisson
la source
1

Je pense que la meilleure façon d'exécuter cette commande:

**rake db:reset** it does db:drop, db:setup
 rake db:setup does db:create, db:schema:load, db:seed
Thorin
la source
1

Vous pouvez simplement exécuter

rake db:setup

Il supprimera la base de données, créera une nouvelle base de données et remplira db à partir de la graine si vous avez créé un fichier de graine avec certaines données.

Touseef Murtaza
la source
1

3 options, même résultat:

1. Toutes les étapes:

  $ rake db:drop           # deletes the database for the current env
  $ rake db:create         # creates the database for the current env
  $ rake db:schema:load    # loads the schema already generated from schema.rb / erases data
  $ rake db:seed           # seed with initial data

2. Réinitialiser:

  $ rake db:reset          # drop / schema:load / seed

3. Migrer: réinitialiser:

  $ rake db:migrate:reset  # drop / create / migrate
  $ rake db:seed

Remarques:

  • Si schema: load est utilisé est plus rapide que de faire toutes les migrations, mais même résultat.
  • Toutes les données seront perdues.
  • Vous pouvez exécuter plusieurs râteaux sur une seule ligne.
  • Fonctionne avec les rails 3.
urko
la source
0

Aujourd'hui, j'ai apporté plusieurs modifications à mon schéma de rails. J'ai réalisé que j'avais besoin de deux modèles supplémentaires dans une hiérarchie et de certains autres à supprimer. De nombreux petits changements ont été nécessaires sur les modèles et les contrôleurs.

J'ai ajouté les deux nouveaux modèles et les ai créés en utilisant:

rake db:migrate

J'ai ensuite édité le fichier schema.rb. J'ai supprimé manuellement les anciens modèles qui n'étaient plus nécessaires, j'ai changé le champ de clé étrangère selon les besoins et l'ai juste réorganisé un peu pour le rendre plus clair pour moi. J'ai supprimé toutes les migrations, puis relancé la génération via:

rake db:reset

Cela a parfaitement fonctionné. Bien entendu, toutes les données doivent être rechargées. Rails s'est rendu compte que les migrations avaient été supprimées et a réinitialisé la ligne des hautes eaux:

-- assume_migrated_upto_version(20121026094813, ["/Users/sean/rails/f4/db/migrate"])
ardochhigh
la source