Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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 from
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.