Refactored the migration script to use the syncdb signal. The post_migrate signal only fires for south-managed apps, so it isn't as useful.

This commit is contained in:
Corey Oordt 2012-08-28 06:56:55 -05:00
parent a92ab30f9c
commit e41623b4ad

View file

@ -1,24 +1,27 @@
from django.db import models, DatabaseError
from django.core.exceptions import ImproperlyConfigured
from .fields import CategoryM2MField, CategoryFKField
from .models import Category
from .settings import FIELD_REGISTRY
def migrate_app(app, *args, **kwargs):
def migrate_app(sender, app, created_models, verbosity, *args, **kwargs):
"""
Migrate all models of this app registered
"""
from .fields import CategoryM2MField, CategoryFKField
from .models import Category
from .settings import FIELD_REGISTRY
import sys
import StringIO
org_stderror = sys.stderr
sys.stderr = StringIO.StringIO() # south will print out errors to stderr
try:
from south.db import db
except ImportError:
raise ImproperlyConfigured("South must be installed for this command to work")
# pull the information from the registry
if not isinstance(app, basestring):
return
fields = [fld for fld in FIELD_REGISTRY.keys() if fld.startswith(app)]
app_name = app.__name__.split('.')[-2]
fields = [fld for fld in FIELD_REGISTRY.keys() if fld.startswith(app_name)]
# call the south commands to add the fields/tables
for fld in fields:
app_name, model_name, field_name = fld.split('.')
@ -28,21 +31,23 @@ def migrate_app(app, *args, **kwargs):
mdl = models.get_model(app_name, model_name)
if isinstance(FIELD_REGISTRY[fld], CategoryFKField):
print "Adding ForeignKey %s to %s" % (field_name, model_name)
try:
db.start_transaction()
table_name = mdl._meta.db_table
FIELD_REGISTRY[fld].default = -1
db.add_column(table_name, field_name, FIELD_REGISTRY[fld], keep_default=False)
db.commit_transaction()
if verbosity:
print "Added ForeignKey %s to %s" % (field_name, model_name)
except DatabaseError, e:
db.rollback_transaction()
if "already exists" in str(e):
print "Already exists"
if verbosity > 1:
print "ForeignKey %s to %s already exists" % (field_name, model_name)
else:
sys.stderr = org_stderror
raise e
elif isinstance(FIELD_REGISTRY[fld], CategoryM2MField):
print "Adding Many2Many table between %s and %s" % (model_name, 'category')
table_name = "%s_%s" % (mdl._meta.db_table, 'categories')
try:
db.start_transaction()
@ -53,12 +58,17 @@ def migrate_app(app, *args, **kwargs):
))
db.create_unique(table_name, ['%s_id' % model_name, 'category_id'])
db.commit_transaction()
if verbosity:
print "Added Many2Many table between %s and %s" % (model_name, 'category')
except DatabaseError, e:
db.rollback_transaction()
if "already exists" in str(e):
print "Already exists"
if verbosity > 1:
print "Many2Many table between %s and %s already exists" % (model_name, 'category')
else:
sys.stderr = org_stderror
raise e
sys.stderr = org_stderror
def drop_field(app_name, model_name, field_name):
@ -67,6 +77,8 @@ def drop_field(app_name, model_name, field_name):
"""
# Table is typically appname_modelname, but it could be different
# always best to be sure.
from .fields import CategoryM2MField, CategoryFKField
from .settings import FIELD_REGISTRY
try:
from south.db import db
except ImportError:
@ -95,9 +107,3 @@ def drop_field(app_name, model_name, field_name):
except DatabaseError, e:
db.rollback_transaction()
raise e
try:
from south.signals import post_migrate
post_migrate.connect(migrate_app)
except ImportError:
pass