Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

comparedb improvements (ignoring, more context, error handling) #52

Merged
merged 6 commits into from Jan 4, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 47 additions & 9 deletions nashvegas/management/commands/comparedb.py
Expand Up @@ -12,6 +12,26 @@
NASHVEGAS = getattr(settings, "NASHVEGAS", {})


def ignorable_sql(line, level):
if level == 0:
return False # ignore nothing

# level 1 = ignore comments
if level > 0 and line.lstrip().startswith("--"):
return True

# level 2 = ignore constraints
if level > 1 and line.lstrip().lower().startswith("add constraint"):
return True

return False


def normalize_sql(lines, level=1):
""" perform simple normalization: remove comments """
return [line for line in lines if not ignorable_sql(line, level)]


class Command(BaseCommand):

option_list = BaseCommand.option_list + (
Expand All @@ -26,6 +46,17 @@ class Command(BaseCommand):
default=DEFAULT_DB_ALIAS,
help="Nominates a database to synchronize. "
"Defaults to the \"default\" database."),
make_option("-l", "--lines-of-context",
action="store",
dest="lines",
default=10,
help="Show this amount of context (default 10)."),
make_option("-i", "--ignore-level",
action="store",
dest="ignore",
default=1,
help="Ignore level. 0=ignore nothing, 1=ignore comments (default), "
"2=ignore constraints"),
)
help = "Checks for schema differences."

Expand All @@ -48,6 +79,9 @@ def handle(self, *args, **options):
self.db = options.get("database", DEFAULT_DB_ALIAS)
self.current_name = connections[self.db].settings_dict["NAME"]
self.compare_name = options.get("db_name")
self.lines = options.get("lines")
self.ignore = int(options.get('ignore'))

if not self.compare_name:
self.compare_name = "%s_compare" % self.current_name

Expand All @@ -64,14 +98,18 @@ def handle(self, *args, **options):
self.setup_database()
connections[self.db].close()
connections[self.db].settings_dict["NAME"] = self.compare_name
call_command("syncdb", interactive=False, verbosity=0)
new_sql = Popen(
command.format(dbname=self.compare_name).split(),
stdout=PIPE
).stdout.readlines()
connections[self.db].close()
connections[self.db].settings_dict["NAME"] = self.current_name
self.teardown_database()
try:
call_command("syncdb", interactive=False, verbosity=0, migrations=False)
new_sql = Popen(
command.format(dbname=self.compare_name).split(),
stdout=PIPE
).stdout.readlines()
finally:
connections[self.db].close()
connections[self.db].settings_dict["NAME"] = self.current_name
self.teardown_database()

print "Outputing diff between the two..."
print "".join(difflib.unified_diff(current_sql, new_sql))
print "".join(difflib.unified_diff(normalize_sql(current_sql, self.ignore),
normalize_sql(new_sql, self.ignore),
n=int(self.lines)))
29 changes: 20 additions & 9 deletions nashvegas/management/commands/syncdb.py
@@ -1,23 +1,34 @@
from django.core.management import call_command
from django.core.management.commands.syncdb import Command as SyncDBCommand
from optparse import make_option


class Command(SyncDBCommand):
option_list = SyncDBCommand.option_list + (
make_option('--skip-migrations',
action='store_false',
dest='migrations',
default=True,
help='Skip nashvegas migrations, do traditional syncdb'),
)

def handle_noargs(self, **options):
# Run migrations first
if options.get("database"):
databases = [options.get("database")]
else:
databases = None

call_command(
"upgradedb",
do_execute=True,
databases=databases,
interactive=options.get("interactive"),
verbosity=options.get("verbosity"),
)

migrations = options.get('migrations')

if migrations:
call_command(
"upgradedb",
do_execute=True,
databases=databases,
interactive=options.get("interactive"),
verbosity=options.get("verbosity"),
)

# Follow up with a syncdb on anything that wasnt included in migrations
# (this catches things like test-only models)
super(Command, self).handle_noargs(**options)