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

Tested and documented comparedb update #37

Closed
wants to merge 3 commits into from
Closed
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
112 changes: 94 additions & 18 deletions docs/index.rst
Expand Up @@ -57,24 +57,6 @@ Options for upgradedb
`./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 Expand Up @@ -110,6 +92,100 @@ product codes on next release::
product.code = "NEW-%s" % product.code
product.save()

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

The `comparedb` command is available only for advanced system administrators.
It proceeds as such:

* get the SQL structure dump of the current database
* create a new database, the "compare" database
* syncdb in the "compare" database,
* get the SQL structure dump of the "compare" database
* output the diff

It executes a few raw 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.

Example for PostgreSQL
``````````````````````

By default, nashvegas executes raw `createdb`, `dropdb` or `pg_dump` commands,
example customisation::

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


If you add a field "test" on model "Foo", comparedb will output::

>>> ./manage.py comparedb
Getting schema for current database...
Getting schema for fresh database...
Outputing diff between the two...
---
+++
@@ -515,7 +515,8 @@

CREATE TABLE testapp_foo (
id integer NOT NULL,
- bar character varying(100)
+ bar character varying(100),
+ test character varying(100)
);

Example for MySQL
`````````````````

MySQL is not supported by default thought such settings do work::

NASHVEGAS = {
"createdb": "mysql -u root -p -e \"create database {dbname}\"",
"dropdb": "mysql -u root -p -e \"drop database {dbname}\"",
"dumpdb": "mysqldump -u root -p {dbname}",
}

If you add a field "test" on model "Foo", comparedb will output::

>>> ./manage.py comparedb
Getting schema for current database...
Enter password:
Getting schema for fresh database...
Enter password:
Enter password:
Enter password:
Outputing diff between the two...
---
+++
@@ -1,6 +1,6 @@
-- MySQL dump 10.13 Distrib 5.1.58, for debian-linux-gnu (x86_64)
--
--- Host: localhost Database: testproject
+-- Host: localhost Database: testproject_compare
-- ------------------------------------------------------
-- Server version 5.1.58-1ubuntu1

@@ -419,6 +419,7 @@
CREATE TABLE `testapp_foo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`bar` varchar(100) DEFAULT NULL,
+ `test` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -441,4 +442,4 @@
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

--- Dump completed on 2012-03-07 12:58:15
+-- Dump completed on 2012-03-07 12:58:18

Typicall customisation would be to setup a `$HOME/.my.cnf` that contains
credentials allowing to run this command without password prompt.

Indices and tables
==================
Expand Down
42 changes: 17 additions & 25 deletions nashvegas/management/commands/comparedb.py
Expand Up @@ -9,7 +9,7 @@
from django.core.management.base import BaseCommand


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


class Command(BaseCommand):
Expand All @@ -24,16 +24,12 @@ class Command(BaseCommand):
help = "Compares current database with the one that nashvegas will build from scratch."

def setup_database(self):
command = "createdb %s" % self.name
if NASHVEGAS and "createdb" in settings.NASHVEGAS:
command = "%s %s" % (settings.NASHVEGAS["createdb"], self.name)
Popen(command.split()).wait()
command = NASHVEGAS.get("createdb", "createdb {dbname}")
Popen(command.format(dbname=self.compare_name), shell=True).wait()

def teardown_database(self):
command = "dropdb %s" % self.name
if NASHVEGAS and "dropdb" in settings.NASHVEGAS:
command = "%s %s" % (settings.NASHVEGAS["dropdb"], self.name)
Popen(command.split()).wait()
command = NASHVEGAS.get("dropdb", "dropdb {dbname}")
Popen(command.format(dbname=self.compare_name), shell=True).wait()

def handle(self, *args, **options):
"""
Expand All @@ -44,30 +40,26 @@ def handle(self, *args, **options):
report the diffs to the user.
"""
self.db = options.get("database", DEFAULT_DB_ALIAS)
self.name = options.get("db_name")
if not self.name:
self.name = "%s_compare" % connections.databases[self.db]["NAME"]

command = "pg_dump -s %s" % connections[self.db].settings_dict["NAME"]
if NASHVEGAS and "pg_dump" in settings.NASHVEGAS:
command = "%s -s %s" % (settings.NASHVEGAS["pg_dump"],
connections[self.db].settings_dict["NAME"])

self.current_name = connections[self.db].settings_dict["NAME"]
self.compare_name = options.get("db_name")
if not self.compare_name:
self.compare_name = "%s_compare" % self.current_name

command = NASHVEGAS.get("dumpdb", "pg_dump -s {dbname}")

print "Getting schema for current database..."
print command
current_sql = Popen(command.split(), stdout=PIPE).stdout.readlines()
current_sql = Popen(command.format(dbname=self.current_name),
shell=True, stdout=PIPE).stdout.readlines()

print "Getting schema for fresh database..."
self.setup_database()
orig = connections[self.db].settings_dict["NAME"]
connections[self.db].close()
connections[self.db].settings_dict["NAME"] = self.name
connections[self.db].settings_dict["NAME"] = self.compare_name
call_command("syncdb", interactive=False, verbosity=0)
print command
new_sql = Popen(command.split() + ["-s", self.name],
new_sql = Popen(command.format(dbname=self.compare_name).split(),
stdout=PIPE).stdout.readlines()
connections[self.db].close()
connections[self.db].settings_dict["NAME"] = orig
connections[self.db].settings_dict["NAME"] = self.current_name
self.teardown_database()

print "Outputing diff between the two..."
Expand Down