为了将来参考,这就是我最终这样做的方式:
if args.settings_dir not in sys.path:
sys.path.append(args.settings_dir)
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
#try to query db for existing objects, e.g. user groups
#in order to detect if we are upgrading an existing installation
from django.db.utils import DatabaseError
try:
from django.contrib.auth.models import Group
tmp = len(Group.objects.all()) #evaluate to force db query
updating = True
except DatabaseError as e:
updating = False
#try to query db for South migrations in order to detect if South was already applied
#in this installation (if not then accessing MigrationHistory will throw an excepion)
try:
from south.models import MigrationHistory
has_south = bool(len(MigrationHistory.objects.all()))
except ImportError as e:
print 'ERROR: Error importing South migration history: ' + str(e)
print 'Exiting'
exit(1)
except DatabaseError as e:
has_south = False
#syncdb to create south_migrationhistory table, portal models will not be synced
from django.core.management import execute_from_command_line
argv = ['manage.py', 'syncdb', '--settings=settings', '--pythonpath=' + args.settings_dir]
execute_from_command_line(argv)
#if we are updating existing installation and South wasn't already applied
#then initial migration has to be 'faked' in order to sync with existing tables
if updating and not has_south:
print 'INFO: Faking initial database migration...'
argv = ['manage.py', 'migrate', '--all', '0001', '--fake',
'--settings=settings', '--pythonpath=' + args.settings_dir]
execute_from_command_line(argv)
#run normal migrations
print 'INFO: Applying database migrations...'
argv = ['manage.py', 'migrate', '--all',
'--settings=settings', '--pythonpath=' + args.settings_dir]
execute_from_command_line(argv)