web-dev-qa-db-fra.com

Quel est le moyen préféré de gérer schema.rb dans git?

Je ne veux pas ajouter schema.rb à .gitignore, car je veux pouvoir charger un nouveau schéma de base de données à partir de ce fichier. Cependant, garder cette option en mémoire est à l’origine de toutes sortes de conflits parasites faciles à résoudre par un nouveau db:migrate:reset.

En gros, je veux un moyen de:

  1. Conservez schema.rb dans le référentiel pour la configuration de la base de données deploy-time
  2. Conservez schema.rb dans '.gitignore' pour le développement général

Il y aurait une ou deux personnes responsables de la mise à jour de schema.rb et de savoir que c'était correct.

Y a-t-il un moyen de prendre mon gâteau et de le manger aussi?

49
Otto

Ce qui a vraiment bien fonctionné pour moi, c’est de supprimer et .gitignore schema.rb, puis de le régénérer pour chaque développeur lorsqu’il rake db:migrate.

Vous pouvez toujours réaliser ce que vous vouliez sans migrer de 0 à 0 et risquer des migrations interrompues d'il y a des années en effectuant simplement un "cumul" des migrations périodiquement. Vous pouvez le faire en:

  1. Exécuter toutes les migrations en attente avec rake db:migrate
  2. Prendre le contenu de votre schema.rb dans le bloc ActiveRecord::Schema.define
  3. Collez-le dans votre migration initial_schema à l'intérieur de def up (en écrasant ce qui existe déjà).
  4. Supprimer toutes les autres migrations

Désormais, votre migration initial_schema constitue votre point de départ pour de nouveaux systèmes et vous n'avez pas à vous soucier des conflits dans schema.rb qui pourraient ne pas être résolus correctement. Ce n'est pas magique, mais ça marche.

2
Tom Harris

Je crains que la solution magique que vous recherchez n'existe pas. Ce fichier est normalement géré dans le contrôle de version, puis pour tout conflit sur la ligne de version, choisissez simplement la dernière des deux dates. Tant que vous exécutez toutes les migrations associées, rien ne doit être désynchronisé de cette façon. Si deux développeurs ont provoqué des modifications dans une zone similaire de schema.rb et que vous obtenez des conflits en plus de la version, vous êtes confronté à une résolution de conflit de fusion normale, mais à mon avis, elles sont normalement faciles à comprendre et à résoudre. J'espère que ça a aidé!

21
Adam Alexander

Une autre chose que vous pouvez faire est d'utiliser:

git update-index --assume-unchanged /path/schema.rb

Cela gardera le fichier dans le référentiel mais ne suivra pas les changements. vous pouvez changer le suivi à tout moment en utilisant:

git update-index --no-assume-unchanged /path/schema.rb
8
Headshota

Au lieu d'utiliser .gitignore, utilisez des branches distinctes: Develop qui omet schema.rb et Test et Deploy qui incluent schema.rb. N'effectuez que des modifications de code dans les branches de développement et ne fusionnez jamais de Test dans Develop. Conservez schema.rb dans une branche distincte:

Developer A             
    Develop      --------             
    Local Schema          \           Your Repo
    Test                    --------->    Dev A
                            --------->    Dev B
Developer B               /               Master
    Develop      --------                 Schema
    Local Schema                          Test
    Test                                  Deploy

Dans Git, les branches sont des pointeurs sur des collections de contenus de fichiers, elles peuvent donc inclure ou exclure des fichiers particuliers ainsi que les versions de fichiers de suivi. Cela en fait des outils flexibles pour construire votre flux de travail particulier.

1
Paul

Vous pouvez définir une stratégie de fusion. J'ai trouvé cette solution, mais ne me souviens pas de la source

[merge "railsschema"]
name = newer Rails schema version
driver = "Ruby -e '\n\
    system %(git), %(merge-file), %(--marker-size=%L), %(%A), %(%O), %(%B)\n\
    b = File.read(%(%A))\n\
    b.sub!(/^<+ .*\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n=+\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n>+ .*/) do\n\
      %(ActiveRecord::Schema.define(:version => #{[$1, $2].max}) do)\n\
    end\n\
    File.open(%(%A), %(w)) {|f| f.write(b)}\n\
    exit 1 if b.include?(%(<)*%L)'"

mettre ce "quelque part" et

git-config --global core.attributesfile "somewhere"
1
andrea

J'ai construit un petit bijou pour résoudre ce problème.

Il trie les colonnes, les noms d'index et les clés étrangères, supprime les espaces blancs en excès et exécute Rubocop pour un certain formatage afin d'unifier la sortie de votre fichier schema.rb.

https://github.com/jakeonrails/fix-db-schema-conflicts

Après l'avoir ajouté à votre Gemfile, vous exécutez simplement rake db:migrate ou rake db:schema:dump comme d'habitude.

1
jakeonrails

Serait-il suffisant de faire un rake db: dump dans un hook git pré-commit?

Ce qui suit ne résoudra pas nécessairement (1) ou (2), mais il pourrait régler le problème de la fusion, puis peut-être que (1) et (2) disparaîtront.

1
dbrown0708
  1. Valider le fichier schema.rb.
  2. Lancer git pull (ou continuer avec ce que vous faites)

Chaque fois que vous migrez la base de données, le fichier schema.rb est mis à jour et apparaît dans git status. Lorsque vous travaillez sur quelque chose et que vous utilisez occasionnellement git pull, cela peut être ennuyeux car vous devez valider le fichier schema.rb avant d'extraire pour résoudre le conflit. Cela signifie que chaque fois que vous migrez la base de données, vous devez valider le fichier schema.rb.

0
Chemist