Django South - la table existe déjà


188

J'essaye de démarrer avec South. J'avais une base de données existante et j'ai ajouté South ( syncdb, schemamigration --initial).

Ensuite, j'ai mis models.pyà jour pour ajouter un champ et j'ai couru ./manage.py schemamigration myapp --auto. Il a semblé trouver le terrain et a dit que je pourrais l'appliquer avec ./manage.py migrate myapp. Mais, faire cela a donné l'erreur:

django.db.utils.DatabaseError: table "myapp_tablename" already exists

tablenameest le premier tableau répertorié dans models.py.

J'utilise Django 1.2, South 0.7

Réponses:


311

puisque vous avez déjà les tables créées dans la base de données, il vous suffit d'exécuter la migration initiale en tant que faux

./manage.py migrate myapp --fake

assurez-vous que le schéma des modèles est identique au schéma des tables de la base de données.


1
Je l'ai Merci. Il s'agit en fait de migrer et non de schemamigration, mais votre réponse m'a amené dans la bonne direction.
Steve

1
mon erreur vient de copier la commande d'OP, commande correcte ./manage.py migrer myapp --fake
Ashok

Cette solution n'a pas résolu le problème dans mon cas. Je n'ai pas modifié la base de données et j'ai écrasé certaines vues car le champ n'a pas été créé sur la table. J'ai dû commenter la nouvelle propriété, migrer à nouveau avec un faux pour tout rétablir, et la deuxième fois que j'ai essayé, cela a fonctionné, ce que je ne comprends toujours pas ... :)
Mc-

1
@Ashok peut-être que vous devriez également préciser que nous devons refaire un schemamigrationavant migrateau cas où nous aurions déjà fait des modifications avant la dernière schemamigration.
Pierre de LESPINAY

3
Cela ne m'a pas aidé. J'avais déjà une table dans ma base de données, et après avoir simulé la migration, il n'y avait aucun moyen d'ajouter les autres tables qui étaient truquées. J'ai dû abandonner toutes les tables et repartir à zéro.
Shailen

41

Bien que la table "myapp_tablename" existe déjà une erreur d'arrêt après que j'ai fait ./manage.py migrer myapp --fake, DatabaseError n'affiche pas une telle colonne: myapp_mymodel.added_field.

J'ai exactement le même problème!

1.Firstly vérifier le numéro de la migration qui est à l' origine de cette. Supposons que ce soit: 0010.

2.Vous devez:

./manage.py schemamigration myapp --add-field MyModel.added_field
./manage.py migrate myapp

s'il manque plus d'un champ, vous devez le répéter pour chaque champ.

3.Maintenant, vous arrivez avec un tas de nouvelles migrations, alors supprimez leurs fichiers de myapp / migrations (0011 et plus si vous aviez besoin d'ajouter plusieurs champs).

4. exécutez ceci:

./manage.py migrate myapp 0010

Maintenant, essayez ./manage.py migrer myapp

Si cela n'échoue pas, vous êtes prêt. Vérifiez simplement si un champ n'est pas manquant.

ÉDITER:

Ce problème peut également se produire lorsque vous disposez d'une base de données de production pour laquelle vous installez South et que la première migration initiale créée dans un autre environnement duplique ce que vous avez déjà dans votre base de données. La solution est bien plus simple ici:

  1. Faux la première migration:

    ./manage migrer myapp 0001 --fake

  2. Rouler avec le reste des migrations:

    ./manage migrer myapp


10

Lorsque j'ai rencontré cette erreur, cela avait une cause différente.

Dans mon cas, South avait en quelque sorte laissé dans ma base de données une table vide temporaire, qui est utilisée dans _remake_table () . J'avais probablement interrompu une migration d'une manière que je n'aurais pas dû. Dans tous les cas, chaque nouvelle migration ultérieure, quand il a appelé _remake_table (), vomissait l'erreur sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already exists, parce qu'il n'existent déjà et ne devait pas être là.

Le morceau _south_new me semblait étrange, alors j'ai parcouru ma base de données, j'ai vu la table _south_new_myapp_mymodel, me suis gratté la tête, j'ai regardé la source de South , j'ai décidé que c'était une poubelle, j'ai laissé tomber la table, et tout allait bien.


C'est ce que j'ai vu, et si j'avais trouvé cela, m'aurait sauvé une demi-heure de mal de cerveau. Assez désagréable - mais ce sont des tables de migration temporaires, et sont laissées pendant une migration échouée, probablement à des fins d'inspection. Le mien s'est produit en raison d'un problème d'intégrité de la base de données lors de la tentative de migration.
Danny Staple

Cela doit être plus haut! Si vous utilisez une base de données sans transactions de schéma, cela peut se produire assez facilement
Yuji 'Tomita' Tomita

2

Si vous rencontrez des problèmes avec vos modèles ne correspondant pas à votre base de données, comme @pielgrzym, et que vous souhaitez migrer automatiquement la base de données pour qu'elle corresponde au dernier fichier models.py (et effacer toutes les données qui ne seront pas recréées par les appareils pendant migrate):

manage.py schemamigration myapp --initial
manage.py migrate myapp --fake
manage.py migrate myapp zero
manage.py migrate myapp

Cela supprimera et recréera uniquement les tables de base de données qui existent dans votre dernier models.pyfichier, de sorte que vous pouvez avoir des tables de déchets dans votre base de données des syncdbs ou migrates précédents . Pour vous en débarrasser, faites précéder toutes ces migrations avec:

manage.py sqlclear myapp | manage.py sqlshell

Et si cela laisse encore des CRUFT traîner dans votre base de données, vous devrez faire un inspectdbet créer le models.pyfichier à partir de cela (pour les tables et l'application que vous souhaitez effacer) avant de faire le sqlclear, puis de restaurer votre models.py d'origine avant créer la --initialmigration et y migrer. Tout cela pour éviter de jouer avec la saveur particulière de SQL dont votre base de données a besoin.


1

Perform these steps in order may help you:

1) python manage.py schemamigration apps.appname --initial

L'étape ci-dessus crée le dossier de migration par défaut.

2) python manage.py migrer apps.appname --fake

génère une fausse migration.

3) python manage.py schemamigration apps.appname --auto

Ensuite, vous pouvez ajouter des champs comme vous le souhaitez et exécuter la commande ci-dessus.

4) python manage.py migrer apps.appname


1

Si vous avez une base de données et une application existantes, vous pouvez utiliser la commande de conversion sud

./manage.py convert_to_south myapp

Cela doit être appliqué avant d'apporter des modifications à ce qui se trouve déjà dans la base de données.

La commande convert_to_south ne fonctionne entièrement que sur la première machine sur laquelle vous l'exécutez. Une fois que vous avez validé les migrations initiales qu'il a effectuées dans votre VCS, vous devrez exécuter ./manage.py migrate myapp 0001 --fakesur chaque machine qui a une copie de la base de code (assurez-vous d'abord qu'elles étaient à jour avec les modèles et le schéma). réf: http://south.readthedocs.org/en/latest/convertinganapp.html


0

En tant que solution temporaire, vous pouvez commenter la création de la table dans le script de migration.

class Migration(migrations.Migration):

    dependencies = [
        (...)
    ]

    operations = [
        #migrations.CreateModel(
        #    name='TABLE',
        #    fields=[
        #            ....
        #            ....
        #    ],
        #),
        ....
        ....

Ou

Si la table existante ne contient aucune ligne (vide), envisagez de supprimer la table comme ci-dessous. (Ce correctif est recommandé uniquement si la table ne contient aucune ligne) . Assurez-vous également de cette opération avant l'opération createModel.

class Migration(migrations.Migration):

    dependencies = [
        (...),
    ]

    operations = [
        migrations.RunSQL("DROP TABLE myapp_tablename;")
    ]

0

Encore une solution (peut-être une solution temporaire).

$ python manage.py sqlmigrate APP_NAME MIGRATION_NAME

par exemple.,.

$ python manage.py sqlmigrate users 0029_auto_20170310_1117

Cela listera toutes les migrations dans les requêtes SQL brutes. Vous pouvez sélectionner les requêtes que vous souhaitez exécuter en évitant la partie qui crée la table existante

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.