Commit 93cfda2d authored by Vassilios Karakoidas's avatar Vassilios Karakoidas
Browse files

Writing some introductory south examples based on synnefo models.

  * Update README.develop to contain a small guide regarding database
    migration policy
parent a3624d9a
......@@ -13,6 +13,7 @@ Synnefo is written in Python 2.6 and depends on the following Python modules
- pycurl [pycurl==7.19.0]
- python-dateutil [python-dateutil==1.4.1]
WARNING: version python-dateutil==2.0 downloaded by pip known *not* to work with Python 2.6
- south [south==0.7.1]
also, depending on the database engine of choice, on one of the following:
- MySQL-python [MySQL-python==1.2.3]
......@@ -27,7 +28,7 @@ The easiest method is to setup a working environment through virtualenv.
Alternatively, you can use your system's package manager to install
the dependencies (e.g. Macports has them all).
*On Snow Leopard, you have to set the following environment variable for
*On Snow Leopard and linux (64-bit), you have to set the following environment variable for
pip to compile the dependencies correctly.
$export ARCHFLAGS="-arch x86_64"
......@@ -185,6 +186,47 @@ username
9. (Hopefully) Done
South Database Migration
------------------------
First, remember to add the south app to settings.py (it is already included in the
settings.py.dist).
In addition, do not use the syncdb management command. Only the first time
The first time (is not required, since when you read this documentation the migration
is already active) the migration of the schema will initialised with the following
command:
$ ./bin/python schemamigration db --initial
Each time you make changes to the database and data migration is not required (WARNING: always
perform this with extreme care):
$ ./bin/python schemamigration db --auto
The above will create the migration script. Now this must be applied to the live database.
$ ./bin/python migrate db
Consider this example (adding a field to the SynnefoUser model):
bkarak@nefarian:~/devel/synnefo$ ./bin/python manage.py schemamigration db --auto
+ Added field new_south_test_field on db.SynnefoUser
Created 0002_auto__add_field_synnefouser_new_south_test_field.py. You can now apply this migration with: ./manage.py migrate db
bkarak@nefarian:~/devel/synnefo$ ./manage.py migrate db
Running migrations for db:
- Migrating forwards to 0002_auto__add_field_synnefouser_new_south_test_field.
> db:0002_auto__add_field_synnefouser_new_south_test_field
- Loading initial data for db.
Installing json fixture 'initial_data' from '/home/bkarak/devel/synnefo/../synnefo/db/fixtures'.
Installed 1 object(s) from 1 fixture(s)
South needs some extra definitions to the model to preserve and migrate the existing data, for example, if we add a field
in a model, we should declare its default value. If not, south management will propably fail, after indicating the error.
If we need to do data migration as well, for example rename a field, we use tha 'datamigration' management command.
UI Testing
----------
The functional ui tests require the Selenium server and the synnefo app to
......
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'SynnefoUser.new_south_test_field'
db.add_column('db_synnefouser', 'new_south_test_field', self.gf('django.db.models.fields.IntegerField')(default=1), keep_default=False)
def backwards(self, orm):
# Deleting field 'SynnefoUser.new_south_test_field'
db.delete_column('db_synnefouser', 'new_south_test_field')
models = {
'db.debit': {
'Meta': {'object_name': 'Debit'},
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.SynnefoUser']"}),
'vm': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.VirtualMachine']"}),
'when': ('django.db.models.fields.DateTimeField', [], {})
},
'db.disk': {
'Meta': {'object_name': 'Disk'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.SynnefoUser']", 'null': 'True', 'blank': 'True'}),
'size': ('django.db.models.fields.PositiveIntegerField', [], {}),
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'vm': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.VirtualMachine']", 'null': 'True', 'blank': 'True'})
},
'db.flavor': {
'Meta': {'unique_together': "(('cpu', 'ram', 'disk'),)", 'object_name': 'Flavor'},
'cpu': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'disk': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ram': ('django.db.models.fields.IntegerField', [], {'default': '0'})
},
'db.flavorcost': {
'Meta': {'object_name': 'FlavorCost'},
'cost_active': ('django.db.models.fields.PositiveIntegerField', [], {}),
'cost_inactive': ('django.db.models.fields.PositiveIntegerField', [], {}),
'effective_from': ('django.db.models.fields.DateTimeField', [], {}),
'flavor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Flavor']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'db.image': {
'Meta': {'object_name': 'Image'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.SynnefoUser']", 'null': 'True', 'blank': 'True'}),
'sourcevm': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.VirtualMachine']", 'null': 'True'}),
'state': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
},
'db.imagemetadata': {
'Meta': {'object_name': 'ImageMetadata'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Image']"}),
'meta_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'meta_value': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
'db.limit': {
'Meta': {'object_name': 'Limit'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.SynnefoUser']"}),
'value': ('django.db.models.fields.IntegerField', [], {})
},
'db.synnefouser': {
'Meta': {'object_name': 'SynnefoUser'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'credit': ('django.db.models.fields.IntegerField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'new_south_test_field': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
},
'db.virtualmachine': {
'Meta': {'object_name': 'VirtualMachine'},
'action': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
'backendjobid': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
'backendjobstatus': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
'backendlogmsg': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'backendopcode': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
'charged': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2011, 4, 11, 9, 13, 47, 902166)'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'flavor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Flavor']"}),
'hostid': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipfour': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}),
'ipsix': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'operstate': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.SynnefoUser']"}),
'sourceimage': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.Image']"}),
'suspended': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
},
'db.virtualmachinegroup': {
'Meta': {'object_name': 'VirtualMachineGroup'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'machines': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['db.VirtualMachine']", 'symmetrical': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.SynnefoUser']"}),
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
},
'db.virtualmachinemetadata': {
'Meta': {'object_name': 'VirtualMachineMetadata'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meta_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'meta_value': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
'vm': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['db.VirtualMachine']"})
}
}
complete_apps = ['db']
......@@ -10,6 +10,7 @@ class SynnefoUser(models.Model):
credit = models.IntegerField('Credit Balance')
created = models.DateTimeField('Time of creation', auto_now_add=True)
updated = models.DateTimeField('Time of last update', auto_now=True)
new_south_test_field = models.IntegerField(default=1)
class Meta:
verbose_name = u'Synnefo User'
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment