web-dev-qa-db-fra.com

Les migrations de Django 1.7 ne recréeront pas une table supprimée, pourquoi?

Utiliser les migrations de Django 1.7.

J'ai accidentellement laissé tomber une table dans ma base de données. J'ai supposé qu'en reconduisant la migration, cela recréerait la table, mais non, Django a déclaré "Aucune migration à appliquer".

Comment je demande à Django de recréer la table?

J'ai couru:

> makemigrations - No changes detected
> migrate - No migrations to apply.

J'ai essayé d'apporter une modification au modèle et d'exécuter une nouvelle migration. Elle indique simplement que "la table 'x.test_customer' n'existe pas", ce qui est correct, mais j'espérais qu'elle recréerait la table.

33
Prometheus

Accédez à votre base de données et trouvez la table Django_migrations. Supprimer toutes les lignes qui ont app est égal à votre nom d'application.

Ensuite, faites une makemigrations & migrate qui fonctionnera.

49
J.Q

Une autre solution que j'ai trouvée et fonctionne parfaitement:

Dans Django 1.7:

  1. Supprimer votre dossier de migration

  2. Dans la base de données: DELETE FROM Django_migrations WHERE app = 'app_name'.

    Vous pouvez aussi simplement tronquer ce tableau.

  3. python manage.py makemigrations

  4. python manage.py migrate --fake

Dans Django 1.9.5:

  1. Supprimer votre dossier de migration
  2. Dans la base de données: DELETE FROM Django_migrations WHERE app = 'app_name'.

    Vous pouvez aussi simplement tronquer ce tableau.

  3. python manage.py makemigrations app_name

  4. python manage.py migrate

Cela fonctionne à 100% pour moi!

21
Raúl EL

J'ai en fait trouvé un moyen plus facile de le faire. Vous prétendez que vous annulez ce qui n'existe pas, puis vous migrez à nouveau. Si votre migration 0005 était celle où il crée la table:

python manage.py migrate myapp --fake 0004
python manage.py migrate myapp

Ça devrait être bien après ça!

Si vous devez ignorer les suivants, procédez comme suit:

python manage.py migrate myapp --fake 0004
python manage.py migrate myapp 0005
python manage.py migrate myapp --fake

Ça devrait être bien après ça!

6
johannestaas

Le moyen le plus simple de faire cela sur Django> = 1.9 est d'exécuter les opérations suivantes:

./manage.py migrate app_name zero

Cela supprimera vos tables et inversera toutes les migrations.

2
yekta

Clause de non-responsabilité complète, il s'agit d'une opération destructrice dans certains cas, et je l'utilise principalement pour remigrer des parties du système sans affecter la base de données.  

Avez-vous essayé de le faire via la table Django_migrations? Supprimez simplement les lignes mappées sur l'étiquette de l'application et les noms de migration en question, puis supprimez-les.

+----+-----------------------+----------------------------------------------------------+---------------------+
| id | app                   | name                                                     | applied             |
+----+-----------------------+----------------------------------------------------------+---------------------+
|  1 | contenttypes          | 0001_initial                                             | 2015-03-07 16:32    |
| 30 | homepage              | 0001_initial                                             | 2015-04-02 13:30:44 |
| 31 | homepage              | 0002_auto_20150408_1751                                  | 2015-04-08 12:24:55 |
| 32 | homepage              | 0003_remove_mappinghomepagemoduleinventory_inventoryinfo | 2015-04-09 08:09:59 |
+----+-----------------------+----------------------------------------------------------+---------------------+

Alors maintenant, si je veux supprimer homepage, je peux simplement supprimer les lignes 30, 31, 32.

Bien sûr, puisque vous avez également supprimé les tables, vous devez également modifier Django_content_type:

+----+----------------------------------------+-----------------------+--------------------------------------+
| id | name                                   | app_label             | model                                |
+----+----------------------------------------+-----------------------+--------------------------------------+
|  1 | content type                           | contenttypes          | contenttype                          |
|  2 | session                                | sessions              | session                              |
|  3 | site                                   | sites                 | site                                 |
| 92 | master_homepagemodule_extrafields      | homepage              | masterhomepagemoduleextrafields      |
| 93 | mapping_homepagemodule_inventory       | homepage              | mappinghomepagemoduleinventory       |
| 94 | master_homepagemodule_inventoryfields  | homepage              | masterhomepagemoduleinventoryfields  |
| 95 | mapping_homepagemodule_inventoryfields | homepage              | mappinghomepagemoduleinventoryfields |
| 96 | master_homepagemodule                  | homepage              | masterhomepagemodule                 |
| 97 | mapping_homepagemodule_extrafields     | homepage              | mappinghomepagemoduleextrafields     |
+----+----------------------------------------+-----------------------+--------------------------------------+

Vous devez donc maintenant supprimer les tables dont vous avez besoin de migrer à nouveau en supprimant les lignes pour ces tables.

Je l'ai utilisé quand le temps était compté et que nous avions besoin d'une solution rapide, ou lorsque nous jouons dans le développement.
J'espère que ça vous aidera aussi! 

2
kunl

Dans mon cas dans Django 2.0.2 pour recréer la table supprimée, je devais commenter mes modèles dans myapp, puis migrer avec --fake, décommenter mes modèles et migrer sans --fake

  1. Supprimez vos fichiers de migration dans l'application souhaitée
  2. Merci à raul answer: Dans la base de données: DELETE FROM Django_migrations WHERE app = 'app_name'.
  3. codes de commentaire dans models.py et tous ces modèles d'utilisation dans views, signals et etc (pour éviter les erreurs).
  4. python manage.py makemigrations YOUR_APP_NAME
  5. python manage.py migrate --fake
  6. commentez ce que vous avez commenté à l'étape 3
  7. python manage.py makemigrations YOUR_APP_NAME
  8. migrer sans --fake : python manage.py migrate

Cela devrait résoudre certains problèmes d'utilisateurs.

0
SirSaleh

OK, alors ce que j'ai fait était de ne pas jouer avec les migrations. On dirait que j'ai de temps en temps des problèmes avec les migrations. Et dans ce cas, essayer de rejouer les migrations ne m'a conduit nulle part. Cela n’aurait peut-être pas aidé qu’il y ait eu certaines migrations du Sud-Ouest, ainsi que les nouvelles versions 1.7.

environnement: postgres 9.3

En gros, j'ai restauré une ancienne sauvegarde de ma base de données dans une base de données vide . Ensuite, j'ai évoqué la cible de restauration dans l'utilitaire postgres admin et copié/collé les tables de création à partir de la description de chaque table (il ne m'en restait que 4). Basculé vers ma base de données de test et exécuté dans l'utilitaire sql de pg.

Je ne sais pas, je ne pense pas qu'il soit déraisonnable de supprimer manuellement une table si vous rencontrez des problèmes (elle me semble comme si la séquence de mon champ d'identifiant ne fonctionnait pas), tant que vous pouvez vivre avec la perte de vos données. Les migrations doivent être résilientes dans ce cas d'utilisation.

0
JL Peyret

Je viens de rencontrer cela en construisant une petite application d'apprentissage de Django. Je voulais créer une colonne non nulle pour une table existante. Il y avait trois étapes:

  1. laisse tomber la table
  2. supprimer l'enregistrement dans Django_migrations
  3. supprime la migration pour la table en question
    • si vous exécutez "python manage.py makemigrations posts" avant cette étape, vous obtenez toujours le message "Vous essayez d'ajouter un champ non Nullable"

Pour une application réelle, vous devez fournir une valeur par défaut, comme d'autres l'ont souligné.

0
techbrownbags