Changes between Version 2 and Version 3 of Tutorial3


Ignore:
Timestamp:
04/18/09 10:45:11 (6 years ago)
Author:
andrew
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Tutorial3

    v2 v3  
    105105}}} 
    106106 
    107 This is bad practice. TBC.... 
     107This is bad practice. Instead, as I described above, you should be making three migrations. Starting with your models.py file in the original state, we should: 
     108 
     109 * Add the new `first_name` and `last_name` fields. 
     110 * Run `./manage.py startmigration southdemo add_firstlast_name --auto` - this should make a `0003_add_firstlast_name.py` migration. 
     111 * Run `./manage.py startmigration southdemo migrate_names` - this should create `0004_migrate_names.py` (which will just be a blank template, since we gave startmigration no options) 
     112 * Remove the `name` field from models.py. 
     113 * Run `./manage.py startmigration southdemo remove_name --auto` - this will make `0005_remove_name.py`. 
     114 
     115This process can be extended to any kind of migration - do any additions of fields, then create a blank migration in the middle to add your data migration to, then do another removal of fields. This way, in the middle migration, you have access to both the fields you are moving data from and the fields you're moving it to. 
     116 
     117You can have a look at the 0003 and 0005 migrations if you wish, but they're reasonably standard schema migrations. We're interested in `0004_migrate_names.py` - open it up, and you should see this: 
     118 
     119{{{ 
     120#!python 
     121from south.db import db 
     122from django.db import models 
     123from southdemo.models import * 
     124 
     125class Migration: 
     126     
     127    def forwards(self, orm): 
     128        "Write your forwards migration here" 
     129     
     130     
     131    def backwards(self, orm): 
     132        "Write your backwards migration here" 
     133     
     134     
     135    models = { 
     136        ... cut for clarity ... 
     137    } 
     138     
     139    complete_apps = ['southdemo'] 
     140}}} 
     141 
     142When you run `./manage.py startmigration` with only an app name and a migration name, South will create a skeleton template of a migration for you to fill in - it's much more useful than doing that part yourself. 
     143 
     144Here, we're interested in data migrations, and so we'll be using the ORM. One thing you should note is that the ORM will '''not work during a dry run''' - if you're using MySQL, all migrations are dry-run before each application, and if you're on another database, you should code to make sure your migrations are portable. You have two ways of making ORM code not run during a dry run: 
     145 
     146 * Wrapping the ORM code in an `if not db.dry_run:` block 
     147 * Adding the `no_dry_run = True` statement to the Migration class 
     148 
     149We'll do the latter, since our entire migration will be using the ORM, and in general you should be making migrations this way anyway. Adding it to the class, we get this: 
     150 
     151{{{ 
     152#!python 
     153from south.db import db 
     154from django.db import models 
     155from southdemo.models import * 
     156 
     157class Migration: 
     158     
     159    no_dry_run = True 
     160 
     161    def forwards(self, orm): 
     162        "Write your forwards migration here" 
     163    ... 
     164}}} 
     165 
     166Now, we can start writing our migration. You use the fake ORM just like the normal ORM, but prefixing all models with `orm.`. Thus, our loop to copy the names across might look something like this: 
     167 
     168TBC