Here's what I want to do.
Develop a Django project on a development server with a development database. Run the south migrations as necessary when I change the model.
Save the SQL from each migration, and apply those to the production server when I'm ready to deploy.
Is such a thing possible with South? (I'd also be curious what others do to get your development database changes on production when working with Django)
You can at least inspect the sql generated by doing manage.py migrate --db-dry-run --verbosity=2
. This will not do anything to the database and will show all the sql. I would still make a backup though, better safe than sorry.
python manage.py sqlmigrate <app_label> <migration_name>
You could try logging the SQL queries in db.connection.queries, using a management command that calls the migrate with a dry-run option:
from django.core.management.base import BaseCommand
from django import db
class Command(BaseCommand):
help = 'Output SQL for migration'
def handle(self, *app_labels, **options):
# assumes DEBUG is True in settings
db.reset_queries()
from django.core.management import call_command
kw = {'db-dry-run': 1, 'verbosity': 0}
call_command('migrate', **kw)
for query in db.connection.queries:
print query['sql']
Assuming that south puts everything through the usual db interface that should work. There will be a few extra selects in there when it queries the history table.
You'd put that in a management/commands/print_migration_sql.py
inside your app and then run it:
python manage.py print_migration_sql
It could probably be easily extended to run this only for specific apps etc
When I need to see the SQL that South generates for debugging or verification I just add the following logging settings to my local_settings.LOGGING.loggers:
'django.db.backends': {
'handlers': ['console'],
'level': 'DEBUG',
},
This is a complete example of the logging setting for South:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '[%(asctime)s] %(levelname)s %(name)s %(lineno)d "%(message)s"'
},
'simple': {
'format': '%(levelname)s %(message)s'
},
},
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
},
'loggers': {
'django': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
},
'django.db.backends': {
'handlers': ['console'],
'level': 'DEBUG',
},
}
}
This will output everything including the query that South runs to decide what migrations to run:
[2014-03-12 23:47:31,385] DEBUG django.db.backends 79 "(0.001) SELECT `south_migrationhistory`.`id`, `south_migrationhistory`.`app_name`, `south_migrationhistory`.`migration`, `south_migrationhistory`.`applied` FROM `south_migrationhistory` WHERE `south_migrationhistory`.`applied` IS NOT NULL ORDER BY `south_migrationhistory`.`applied` ASC; args=()"
That and setting verbosity to 2 or 3 is usually more than enough to get a clear picture of what's going on.
I'd either do what Lutger suggested (and maybe write a log parser to strip out just the SQL), or I'd run my migration against a test database with logging enabled on the test DB.
Of course, if you can run it against the test database, you're just a few steps away from validating the migration. If it passes, run it again against production.
来源:https://stackoverflow.com/questions/5833418/django-south-is-there-a-way-to-view-the-sql-it-runs