web-dev-qa-db-fra.com

Django Sud - la table existe déjà)

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

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

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

tablename est la première table répertoriée dans models.py.

Je cours Django 1.2, Sud 0.7

188
Steve

comme vous avez déjà créé les tables 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.

311
Ashok

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

Vous avez exactement le même problème!

1. Tout d'abord vérifiez le numéro de migration qui est à l'origine de cela. Supposons qu'il est: 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 débarquez avec un tas de nouvelles migrations donc 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 ne manque pas, vous êtes prêt. Il suffit de vérifier à nouveau si aucun champ ne manque.

MODIFIER:

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

  1. Faux la première migration:

    ./manage migrate myapp 0001 --fake

  2. Rouler avec le reste des migrations:

    ./manage migrate myapp

41
pielgrzym

Lorsque j'ai rencontré cette erreur, la cause était différente.

Dans mon cas, Sud avait en quelque sorte laissé dans ma base de données une table vide temporaire, 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, lorsqu'elle s'appelle _remake_table (), génère l'erreur sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already exists, parce que existait déjà et n'était pas censé être là.

Le bit _south_new me paraissait étrange, j'ai donc consulté ma base de données et vu la table _south_new_myapp_mymodel, me grattant la tête, regarda source de South , décida que c'était de la malbouffe, laissa tomber la table et tout allait bien.

10
ben author

Perform these steps in order may help you:

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

L’étape ci-dessus crée un 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 à votre guise et exécuter la commande ci-dessus.

4) python manage.py migrer apps.appname

2
Vijesh Venugopal

Si vos modèles ne correspondent pas à votre base de données, par exemple @pielgrzym, et que vous souhaitez migrer automatiquement la base de données pour correspondre au dernier fichier models.py (et effacer toutes les données qui ne seront pas recréées par les fixtures au cours de 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 fichier models.py fichier, vous pouvez donc avoir des tables de mémoire dans votre base de données de syncdbs ou migrates précédentes. Pour vous en débarrasser, faites précéder toutes ces migrations de:

manage.py sqlclear myapp | manage.py sqlshell

Et si cela laisse encore quelques CRUFT traîner dans votre base de données, vous devrez alors faire un inspectdb et créer le models.py fichier à partir de celui-ci (pour les tables et l’application que vous souhaitez effacer) avant de procéder à la sqlclear, puis de restaurer votre fichier models.py original avant de créer le fichier --initial migration et migration vers celle-ci. Tout cela pour éviter de jouer avec le type particulier de SQL dont votre base de données a besoin.

2
hobs

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

Ceci doit être appliqué avant vous apportez des modifications à ce qui est 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 effectuées dans votre VCS, vous devez exécuter ./manage.py migrate myapp 0001 --fake sur chaque ordinateur disposant d'une copie de la base de code (assurez-vous d'abord qu'ils étaient à jour avec les modèles et le schéma). ref: http://south.readthedocs.org/en/latest/convertinganapp.html

1
Tommy Strand

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 la supprimer 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
SuperNova

Une autre 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

Ceci listera toutes les migrations dans les requêtes SQL brutes. Vous pouvez choisir les requêtes que vous voulez exécuter en évitant la partie qui crée la table existante

0
SuperNova