Skip to content

Commit

Permalink
Merge branch 'brutasse-patches'
Browse files Browse the repository at this point in the history
  • Loading branch information
paltman committed Apr 19, 2011
2 parents b026a76 + fac22b8 commit 4b9fbfa
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 21 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ Brian Rosner <brosner@gmail.com>
Jannis Leidel <jannis@leidel.info>
Matt George <mgeorge@gmail.com>
Gautier Hayoun <ghayoun@gmail.com>
Bruno Renié (http://bruno.im/)
26 changes: 23 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,32 @@ Options for upgradedb
---------------------

* ``--create`` - Compares database with current models in apps that are
installed and outputs the sql for them so that you can easily
pipe the contents to a migration.
installed and outputs the sql for them so that you can easily pipe the
contents to a migration.
* ``--list`` - Lists all the scripts that will need to be executed.
* ``--execute`` - Executes all the scripts that need to be executed.
* ``--seed`` - Populates Migration model with scripts that have already been
applied to your database and effectively want to skip execution.
applied to your database and effectively want to skip execution. Provide a
migration id to stop at. For instance, running
`./manage.py upgradedb --seed 005` will skip migrations 000 to 005 but not
006.


Configuration for comparedb
---------------------------

The `comparedb` command is available only for Postgres. It executes a few raw
postgres shell commands which you might need to customize to add user
credentials, encoding or specify database templates. This can be done through
the `NASHVEGAS` dictionnary in your setting::

NASHVEGAS = {
"createdb": "createdb -U postgres -T template0 -E UTF8",
"dropdb": "dropdb -U postgres",
"pg_dump": "pg_dump -U postgres",
}

By default, nashvegas executes raw `createdb`, `dropdb` or `pg_dump` commands.


Conventions
Expand Down
36 changes: 24 additions & 12 deletions nashvegas/management/commands/comparedb.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
from subprocess import PIPE, Popen

from django.db import connections, DEFAULT_DB_ALIAS
from django.conf import settings
from django.core.management import call_command
from django.core.management.base import BaseCommand


NASHVEGAS = getattr(settings, "NASHVEGAS", None)


class Command(BaseCommand):

option_list = BaseCommand.option_list + (
Expand All @@ -16,13 +20,19 @@ class Command(BaseCommand):
help = "The name of the database to hold the truth schema"),
)
help = "Compares current database with the one that nashvegas will build from scratch."

def setup_database(self):
Popen(["createdb", self.name]).wait()

command = "createdb %s" % self.name
if NASHVEGAS and "createdb" in settings.NASHVEGAS:
command = settings.NASHVEGAS["createdb"]
Popen(command.split()).wait()

def teardown_database(self):
Popen(["dropdb", self.name]).wait()

command = "dropdb %s" % self.name
if NASHVEGAS and "dropdb" in settings.NASHVEGAS:
command = settings.NASHVEGAS["dropdb"]
Popen(command.split()).wait()

def handle(self, *args, **options):
"""
Compares current database with a migrations.
Expand All @@ -32,21 +42,23 @@ def handle(self, *args, **options):
report the diffs to the user.
"""
self.name = options.get("db_name")

command = "pg_dump -s %s" % connections[DEFAULT_DB_ALIAS].settings_dict["NAME"]
if NASHVEGAS and "pg_dump" in settings.NASHVEGAS:
command = settings.NASHVEGAS["pg_dump"]

print "Getting schema for current database..."
current_sql = Popen(["pg_dump", "-s", connections[DEFAULT_DB_ALIAS].settings_dict["NAME"]], stdout=PIPE).stdout.readlines()
current_sql = Popen(command.split(), stdout=PIPE).stdout.readlines()

print "Getting schema for fresh database..."
self.setup_database()
orig = connections[DEFAULT_DB_ALIAS].settings_dict["NAME"]
connections[DEFAULT_DB_ALIAS].close()
connections[DEFAULT_DB_ALIAS].settings_dict["NAME"] = self.name
call_command("upgradedb", do_execute=True)
new_sql = Popen(["pg_dump", "-s", self.name], stdout=PIPE).stdout.readlines()
call_command("syncdb", interactive=False, verbosity=0)
new_sql = Popen(command.split(), stdout=PIPE).stdout.readlines()
connections[DEFAULT_DB_ALIAS].close()
connections[DEFAULT_DB_ALIAS].settings_dict["NAME"] = orig
self.teardown_database()

print "Outputing diff between the two..."

print "".join(difflib.unified_diff(current_sql, new_sql))
17 changes: 11 additions & 6 deletions nashvegas/management/commands/upgradedb.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import re
import sys
import traceback

Expand All @@ -18,6 +19,7 @@


sys.path.append("migrations")
MIGRATION_NAME_RE = re.compile(r"(\d+)(.*)")


class MigrationError(Exception):
Expand Down Expand Up @@ -76,10 +78,11 @@ def _filter_down(self, stop_at=None):

for script in in_directory:
name, ext = os.path.splitext(script)
try:
number = int(name.split("_")[0])
except ValueError:
raise MigrationError("Invalid migration file prefix (must begin with a number)")
match = MIGRATION_NAME_RE.match(name)
if match is None:
raise MigrationError("Invalid migration file prefix "
"(must begin with a number)")
number = int(match.group(1))
if ext in [".sql", ".py"]:
scripts_in_directory.append((number, script))

Expand Down Expand Up @@ -122,7 +125,7 @@ def init_nashvegas(self):
# dispatcher events.
for app_name in settings.INSTALLED_APPS:
try:
import_module('.management', app_name)
import_module(".management", app_name)
except ImportError, exc:
# This is slightly hackish. We want to ignore ImportErrors
# if the "management" module itself is missing -- but we don't
Expand All @@ -134,7 +137,7 @@ def init_nashvegas(self):
# CPython uses the text "No module named management"
# PyPy uses "No module named myproject.myapp.management"
msg = exc.args[0]
if not msg.startswith('No module named') or 'management' not in msg:
if not msg.startswith("No module named") or "management" not in msg:
raise

# @@@ make cleaner / check explicitly for model instead of looping over and doing string comparisons
Expand Down Expand Up @@ -245,6 +248,8 @@ def seed_migrations(self, stop_at=None):
stop_at = int(self.args[0])
except ValueError:
raise CommandError("Invalid --seed migration")
except IndexError:
raise CommandError("Usage: ./manage.py upgradedb --seed <stop_at>")
migrations = [os.path.join(self.path, m) for m in self._filter_down(stop_at=stop_at)]
for migration in migrations:
m, created = Migration.objects.get_or_create(
Expand Down

0 comments on commit 4b9fbfa

Please sign in to comment.