mardi 12 août 2014

python - Django 1.5 : Comment puis-je ajouter un nouveau champ de modèle à une table à l'aide au sud sans avoir à supprimer une table ? -Débordement de pile


I am running a Django 5.1 web application live on Heroku, with user data I want to preserve.


Locally, I just added a new char field to an existing model, and don't want to break anything when I push to Heroku. I know Django 6 introduced a migrate command, but Django 5 doesn't have anything like that. I have just the South migration tool.


I tried to follow the South basic tutorial locally (on my sqlite3 db), to make sure it wouldn't break anything when I ran 'for real' up on Heroku. Everything broke...


(venv)$ python manage.py migrate forecasts
Running migrations for forecasts:
- Migrating forwards to 0002_auto__add_field_day_weather.
> forecasts:0001_initial
FATAL ERROR - The following SQL query failed: CREATE TABLE "forecasts_region" ("id" integer NOT NULL PRIMARY KEY, "url" varchar(200) NOT NULL UNIQUE, "name" varchar(200) NOT NULL, "nickname" varchar(10) NOT NULL)
The error was: table "forecasts_region" already exists
! Error found during real run of migration! Aborting.

! Since you have a database that does not support running
! schema-altering statements in transactions, we have had
! to leave it in an interim state between migrations.

! You *might* be able to recover with: = DROP TABLE "forecasts_region"; []
= DROP TABLE "forecasts_day"; []
= DROP TABLE "forecasts_tide"; []

! The South developers regret this has happened, and would
! like to gently persuade you to consider a slightly
! easier-to-deal-with DBMS (one that supports DDL transactions)
! NOTE: The error which caused the migration to fail is further up.
Error in migration: forecasts:0001_initial
DatabaseError: table "forecasts_region" already exists

I was forced to DROP those three tables, then rerun python manage.py syncdb, then python manage.py migrate forecasts. This added the new field, but I lost all my data in those three tables.


I'm terrified of messing things up on the live version, so please, what do I do, in what order? If you can include best practices, for preserving data just in case something goes wrong, that would be greatly appreciated. Also, please hold me by the hand on this one, because I've never used South. Thanks!




You're correct in using Django South for the database migration. The problem with what you ran above is that you already had tables created in your database. South lets you do a "fake" migration the first time you're running migrations, so it doesn't try to create tables that already exist.


You can either try the South command for converting an existing app to South, as explained here http://south.readthedocs.org/en/latest/convertinganapp.html#converting-an-app, or try the following:



  1. Create all tables in your database. you ran this when you first started your project

    python manage.py syncdb

  2. Create the initial migration with South

    python manage.py schemamigration --initial forecasts

  3. Apply it as a fake migration

     python manage.py migrate forecasts --fake

  4. Make the change to the forecasts model.


  5. Create a migration for your new change

     python manage.py schemamigration --auto forecasts

  6. Apply that migration, which will now just have the single alter command

     python manage.py migrate forecasts




Okay, I think I found a good step-by-step process for using South both locally and on Heroku (from this blog):



  • Open settings.py and add 'south' to your list of INSTALLED_APPS

    • Run syncdb locally:

      • python django_project/manage.py syncdb



  • Convert your project to use South:

    • python django_project/manage.py convert_to_south django_app


  • Add some new fields to django_project/django_app/models.py

  • Set up the schema:

    • python django_project/manage.py schemamigration django_app --auto


  • Perform the migration:

    • python django_project/manage.py migrate django_app


  • Add South Heroku project's requirements.txt file. For example:

    • South==0.7.3


  • Add the South django_project/migrations directory to version control and commit all your changes.

  • Push your changes to Heroku:

    • git push heroku master


  • Run syncdb on Heroku:

    • heroku run bin/python django_project/manage.py syncdb


  • Convert your Heroku instance of django_app to use South

    • heroku run bin/python django_project/manage.py convert_to_south django_app


  • Perform the migration:

    • heroku run bin/python django_project/manage.py migrate django_app



Just in case, you can back up a postgres db on heroku, using the PG Backups plugin, as described here.



I am running a Django 5.1 web application live on Heroku, with user data I want to preserve.


Locally, I just added a new char field to an existing model, and don't want to break anything when I push to Heroku. I know Django 6 introduced a migrate command, but Django 5 doesn't have anything like that. I have just the South migration tool.


I tried to follow the South basic tutorial locally (on my sqlite3 db), to make sure it wouldn't break anything when I ran 'for real' up on Heroku. Everything broke...


(venv)$ python manage.py migrate forecasts
Running migrations for forecasts:
- Migrating forwards to 0002_auto__add_field_day_weather.
> forecasts:0001_initial
FATAL ERROR - The following SQL query failed: CREATE TABLE "forecasts_region" ("id" integer NOT NULL PRIMARY KEY, "url" varchar(200) NOT NULL UNIQUE, "name" varchar(200) NOT NULL, "nickname" varchar(10) NOT NULL)
The error was: table "forecasts_region" already exists
! Error found during real run of migration! Aborting.

! Since you have a database that does not support running
! schema-altering statements in transactions, we have had
! to leave it in an interim state between migrations.

! You *might* be able to recover with: = DROP TABLE "forecasts_region"; []
= DROP TABLE "forecasts_day"; []
= DROP TABLE "forecasts_tide"; []

! The South developers regret this has happened, and would
! like to gently persuade you to consider a slightly
! easier-to-deal-with DBMS (one that supports DDL transactions)
! NOTE: The error which caused the migration to fail is further up.
Error in migration: forecasts:0001_initial
DatabaseError: table "forecasts_region" already exists

I was forced to DROP those three tables, then rerun python manage.py syncdb, then python manage.py migrate forecasts. This added the new field, but I lost all my data in those three tables.


I'm terrified of messing things up on the live version, so please, what do I do, in what order? If you can include best practices, for preserving data just in case something goes wrong, that would be greatly appreciated. Also, please hold me by the hand on this one, because I've never used South. Thanks!



You're correct in using Django South for the database migration. The problem with what you ran above is that you already had tables created in your database. South lets you do a "fake" migration the first time you're running migrations, so it doesn't try to create tables that already exist.


You can either try the South command for converting an existing app to South, as explained here http://south.readthedocs.org/en/latest/convertinganapp.html#converting-an-app, or try the following:



  1. Create all tables in your database. you ran this when you first started your project

    python manage.py syncdb

  2. Create the initial migration with South

    python manage.py schemamigration --initial forecasts

  3. Apply it as a fake migration

     python manage.py migrate forecasts --fake

  4. Make the change to the forecasts model.


  5. Create a migration for your new change

     python manage.py schemamigration --auto forecasts

  6. Apply that migration, which will now just have the single alter command

     python manage.py migrate forecasts



Okay, I think I found a good step-by-step process for using South both locally and on Heroku (from this blog):



  • Open settings.py and add 'south' to your list of INSTALLED_APPS

    • Run syncdb locally:

      • python django_project/manage.py syncdb



  • Convert your project to use South:

    • python django_project/manage.py convert_to_south django_app


  • Add some new fields to django_project/django_app/models.py

  • Set up the schema:

    • python django_project/manage.py schemamigration django_app --auto


  • Perform the migration:

    • python django_project/manage.py migrate django_app


  • Add South Heroku project's requirements.txt file. For example:

    • South==0.7.3


  • Add the South django_project/migrations directory to version control and commit all your changes.

  • Push your changes to Heroku:

    • git push heroku master


  • Run syncdb on Heroku:

    • heroku run bin/python django_project/manage.py syncdb


  • Convert your Heroku instance of django_app to use South

    • heroku run bin/python django_project/manage.py convert_to_south django_app


  • Perform the migration:

    • heroku run bin/python django_project/manage.py migrate django_app



Just in case, you can back up a postgres db on heroku, using the PG Backups plugin, as described here.


0 commentaires:

Enregistrer un commentaire