web-dev-qa-db-fra.com

Django migrate --fake et --fake-initial expliqués

Je suis un utilisateur de Django depuis environ 2 ans maintenant et il y a une fonctionnalité que j'ai toujours craint d'utiliser: simulant les migrations .

J'ai regardé à peu près partout et la plupart des informations que je peux obtenir proviennent de documentation où il est indiqué que:

- faux

Indique Django pour marquer les migrations comme ayant été appliquées ou non, mais sans exécuter le code SQL pour modifier le schéma de votre base de données.

Ceci est destiné aux utilisateurs avancés qui manipulent directement l’état actuel de la migration s’ils appliquent manuellement les modifications; Soyez averti que l'utilisation de --fake risque de placer la table d'état de la migration dans un état où la récupération manuelle sera nécessaire pour que les migrations se déroulent correctement.

- fake-initial

Permet à Django) d'ignorer la migration initiale d'une application si toutes les tables de base de données portant les noms de tous les modèles créés par toutes les opérations CreateModel dans cette migration existent déjà. Cette option est destinée à être utilisée lors de la première migration base de données qui préexistait à l’utilisation des migrations. Cette option ne vérifie toutefois pas la correspondance du schéma de base de données au-delà des noms de table correspondants et ne peut donc être utilisée en toute sécurité que si vous êtes sûr que votre schéma existant correspond à ce qui a été enregistré dans votre migration initiale.

Je comprends l'idée générale et pourquoi on voudrait utiliser cette fonctionnalité. Mais je ne comprends pas la partie où il est dit que cela est destiné uniquement aux utilisateurs avancés.

Quelqu'un peut-il expliquer ce qui se passe en coulisse et pourquoi une récupération manuelle serait nécessaire?.

[~ # ~] note [~ # ~]

Je ne cherche pas les requêtes SQL brutes exactes qui s'exécutent lorsque l'on simule une migration. Je cherche seulement une idée générale de ce qui se passe en coulisse et peut-être un exemple de la raison pour laquelle simuler une migration entraînerait un état où makemigrations ne fonctionnerait pas correctement.

21
scharette

Il est lié à un problème de base de données similaire à un conflit de fusion dans le code source (git) si vous devez combiner deux branches avec des modèles similaires ou basculer entre elles. Personne ne l'aime intentionnellement.

Imaginez que vous ayez commencé à modifier une application la semaine dernière, peut-être parce que vous avez trouvé un bogue ou que vous avez étendu l'application à un champ ou à une table. Aujourd'hui, vous avez reçu une mise à jour et vous rencontrez un problème, car une migration ajoute un champ qui se trouve toujours dans votre base de données et vous ne pouvez appliquer que d'autres parties de cette migration. Vous consultez le contenu SQL de la migration en exécutant

./manage sqlmigrate some_app 0007_new_migration >customized-some_app-0007_new_migration.sql

comparez le contenu avec le changement effectué la semaine dernière et supprimez ou commentez une commande qui est toujours appliquée et qui ne peut pas être répétée. Exécutez tous les SQL restants manuellement. Marquez cette migration comme si elle était appliquée automatiquement:

./manage migrate --fake some_app 0007_new_migration

Si vous cassez quelque chose, personne ne pourra probablement vous aider, car le système de migration ne saura pas davantage l’état actuel de la base de données. Faites donc une sauvegarde, rédigez des notes, utilisez un bac à sable et travaillez avec précision.

EDIT: La table de migration Django_migrations est une simple liste de migrations appliquées à toutes les applications. Les lignes de cette table doivent toujours être dans un état synchronisé avec la structure de la base de données. Les migrations peuvent être appliquées par un migrate normal. (ou non appliqué par une migration inverse vers un état plus ancien, généralement avec une perte de données bien sûr) Une fausse migration applique la modification uniquement à la table Django_migrations.

me => select * from Django_migrations;
 id | app      |          name           |            applied            
----+----------+-------------------------+-------------------------------
  1 | some_app | 0001_initial            | 2017-10-16 06:11:07.31249+02
  2 | some_app | 0002_auto_20171016_1905 | 2017-10-17 02:05:48.979295+02

Une migration (fichier) est une description du changement incrémentiel et des informations permettant d'évaluer la différence entre models.py depuis la dernière migration, cela est comparé lors de l'exécution de makemigrations. Cela est également suffisant dans le cas où certaines tables étaient initialement non gérées et pourraient le devenir ultérieurement. (Par conséquent, les tables non gérées sont également enregistrées.)

EDIT: Un exemple: comment sqlmigrate avec --fake pourrait être utilisé pour réparer une base de données endommagée par des migrations (pour recréer une table supprimée).

20
hynekcer