Question

J'ai des lampes avec des données initiales qui doit résider dans ma base de données (pays, régions, transporteurs, etc.). J'ai un râteau de tâche db: graine qui sèmeront une base de données

.
namespace :db do
  desc "Load seed fixtures (from db/fixtures) into the current environment's database." 
  task :seed => :environment do
    require 'active_record/fixtures'

    Dir.glob(RAILS_ROOT + '/db/fixtures/yamls/*.yml').each do |file|
      Fixtures.create_fixtures('db/fixtures/yamls', File.basename(file, '.*'))
    end
  end
end

Je suis un peu inquiet parce que cette tâche efface ma base de données propre et charge les données initiales. Le fait que cela est encore possible de faire plus d'une fois sur la production fait peur la merde hors de moi. Est-ce normal et dois-je juste être prudent? Ou les gens protègent généralement une tâche comme celui-ci en quelque sorte?

Était-ce utile?

La solution

données ensemençant avec des appareils est une très mauvaise idée.

Les luminaires à tubes ne sont pas validés et que la plupart des développeurs Rails ne pas utiliser des contraintes de base de données cela signifie que vous pouvez facilement obtenir des données non valides ou incomplètes insérées dans la base de données de production.

Les luminaires à tubes également Ids clé primaire étrange par défaut, ce qui est pas nécessairement un problème, mais est ennuyeux de travailler avec.

Il y a beaucoup de solutions pour cela. Mon préféré est une tâche de râteau qui exécute un script Ruby qui utilise simplement ActiveRecord pour insérer des enregistrements. C'est ce que Rails 3 fera avec db:seed, mais vous pouvez facilement écrire vous-même.

Je compléterez par une méthode ajouter à ActiveRecord :: Base appelée create_or_update. L'utilisation de ce que je peux exécuter le script de démarrage plusieurs fois, mettre à jour les anciens enregistrements au lieu de lancer une exception.

J'ai écrit un article sur ces techniques un certain temps appelé données de semences de chargement .

Autres conseils

Pour la première partie de votre question, oui, je venais de mettre un peu de précaution pour exécuter une tâche comme celui-ci dans la production. Je mets une protection comme celui-ci dans mon bootstrapping / tâche ensemencement:

task :exit_or_continue_in_production? do
  if Rails.env.production?
    puts "!!!WARNING!!! This task will DESTROY " +
         "your production database and RESET all " +
         "application settings"
    puts "Continue? y/n"
    continue = STDIN.gets.chomp
    unless continue == 'y'
      puts "Exiting..."
      exit! 
    end
  end
end

J'ai créé cet essentiel contexte.

Pour la deuxième partie de la question - généralement vous voulez vraiment deux choses: a) l'ensemencement très facilement la base de données et la mise en place de l'application pour le développement, et b) bootstrapping l'application sur le serveur de production (comme: l'insertion utilisateur admin, la création de l'application des dossiers dépend, etc).

J'utiliser des appareils pour l'ensemencement dans le développement - tout le monde de l'équipe voit alors les mêmes données dans l'application et ce qui est en application est conforme à ce qui est dans les tests. (En général, je conclurai rake app:bootstrap, rake app:seed rake gems:install, etc dans rake app:install afin que chacun puisse travailler sur l'application par tout le clonage du repo et l'exécution de cette tâche une.)

Je l'utilise cependant jamais accessoires pour l'ensemencement / bootstrapping sur le serveur de production. La db/seed.rb Rails est vraiment bien pour cette tâche, mais vous pouvez bien sûr mettre la même logique dans votre propre tâche rake app:seed, comme d'autres ont fait remarquer.

Rails 3 résoudra pour vous en utilisant un fichier seed.rb.

http://github.com/brynary/rails/commit/4932f7b38f72104819022abca0c952ba6f9888cb

Nous avons construit un tas de bonnes pratiques que nous utilisons pour les données d'ensemencement. Nous comptons beaucoup sur l'ensemencement, et nous avons des exigences uniques car nous avons besoin de systèmes semenciers multi-locataires. Voici quelques bonnes pratiques que nous avons utilisé:

  1. Les luminaires à tubes ne sont pas la meilleure solution, mais vous devez toujours stocker vos données de semences dans quelque chose autre que Ruby. Code Ruby pour stocker des données de semences a tendance à se répéter, et le stockage des données dans un fichier analysable signifie que vous pouvez écrire du code générique pour gérer vos graines d'une manière cohérente.
  2. Si vous allez mettre à jour potentiellement des graines, utilisez une colonne de marqueur nommé quelque chose comme code pour correspondre à vos graines fichier à vos données réelles. Ne vous fiez jamais ids être cohérent entre les environnements.
  3. Pensez à la façon dont vous voulez gérer la mise à jour des données de semences existantes. Y at-il possible que les utilisateurs ont modifié ces données? Si oui, vous devez maintenir les informations de l'utilisateur plutôt que de données remplace par des semences?

Si vous êtes intéressé par quelques-unes des façons dont nous n'ensemencement, nous les avons regroupés dans un bijou appelé SeedOMatic .

Que diriez-vous simplement supprimer la tâche de votre serveur de production une fois que vous avez semé la base de données?

Je viens d'avoir une idée intéressante ...

si vous avez créé \ db \ graines \ et ajouté des fichiers de type de migration:

fichier: 200907301234_add_us_states.rb

class AddUsStates < ActiveRecord::Seeds

  def up
    add_to(:states, [
      {:name => 'Wisconsin', :abbreviation => 'WI', :flower => 'someflower'},
      {:name => 'Louisiana', :abbreviation => 'LA', :flower => 'cypress tree'}
      ]
    end
  end

  def down
    remove_from(:states).based_on(:name).with_values('Wisconsin', 'Louisiana', ...)
  end
end

alternativement:

  def up
    State.create!( :name => ... )
  end

Cela vous permettra d'exécuter les migrations et les graines dans un ordre qui leur permettrait de coexister plus pacifique.

pensées?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top