Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

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

Merged
merged 6 commits into from

2 participants

@iivvoo

I've noticed a couple of issues with nashvegas (comparedb):

  • it doesn't always provide enough content to find which table has changed (and it's not always trivial to figure out what the table name should be) -> added a "-l" option to provide lines of context
  • it provides noise by comparing irrelevant data such as comments and "ADD CONSTRAINT" lines. These can be selectively ignored using a "-i " flag
  • if something is wrong with a migration (e.g. an empty .sql file that I was about to write), comparedb no longer works. But more annoying, the compare database is not removed; fixed this.

Additionally, syncdb is make do work again somewhat using the --skip-migrations flag. This allows comparedb to work (create new database+syncdb) if there are migrations (which cannot be applied before the real syncdb has taken place)

@paltman paltman merged commit 6e95ed3 into paltman:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 4, 2012
  1. @iivvoo
  2. @iivvoo
  3. @iivvoo
  4. @iivvoo
  5. @iivvoo

    Fix syncdb, make it work on empty databases again

    iivvoo authored
    The --skip-migrations flag will make it skip the nashvegas migrations,
    which will fail on new, empty databases. This will also make 'comparedb'
    work again if there are migrations in general.
  6. @iivvoo

    whitespace fixes

    iivvoo authored
This page is out of date. Refresh to see the latest.
View
56 nashvegas/management/commands/comparedb.py
@@ -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 + (
@@ -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."
@@ -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
@@ -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)))
View
29 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)
Something went wrong with that request. Please try again.