summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-07-14 20:23:13 +0000
committerGerrit Code Review <review@openstack.org>2014-07-14 20:23:13 +0000
commit3fd851ac7256b32cdc4515c96a2a54371a2dd676 (patch)
treed58c9c683bea8104082970a70a1cb38340f7fa78 /tools
parent74d5945e042dba486064a55048c05369bedf4501 (diff)
parentdcf7e4881c476ff7580a9e3131fb8e90032cf7f4 (diff)
downloadnova-3fd851ac7256b32cdc4515c96a2a54371a2dd676.tar.gz
Merge "Specify DB URL on command-line for schema_diff.py"
Diffstat (limited to 'tools')
-rwxr-xr-xtools/db/schema_diff.py71
1 files changed, 40 insertions, 31 deletions
diff --git a/tools/db/schema_diff.py b/tools/db/schema_diff.py
index fdcad3114c..9e88f4f22c 100755
--- a/tools/db/schema_diff.py
+++ b/tools/db/schema_diff.py
@@ -21,12 +21,24 @@ release into a single file. This is a manual and, unfortunately, error-prone
process. To ensure that the schema doesn't change, this tool can be used to
diff the compacted DB schema to the original, uncompacted form.
+The database is specified by providing a SQLAlchemy connection URL WITHOUT the
+database-name portion (that will be filled in automatically with a temporary
+database name).
The schema versions are specified by providing a git ref (a branch name or
commit hash) and a SQLAlchemy-Migrate version number:
+
Run like:
- ./tools/db/schema_diff.py mysql master:latest my_branch:82
+ MYSQL:
+
+ ./tools/db/schema_diff.py mysql://root@localhost \
+ master:latest my_branch:82
+
+ POSTGRESQL:
+
+ ./tools/db/schema_diff.py postgresql://localhost \
+ master:latest my_branch:82
"""
from __future__ import print_function
@@ -43,10 +55,15 @@ from nova.openstack.common.gettextutils import _
### Dump
-def dump_db(db_driver, db_name, migration_version, dump_filename):
+def dump_db(db_driver, db_name, db_url, migration_version, dump_filename):
+ if not db_url.endswith('/'):
+ db_url += '/'
+
+ db_url += db_name
+
db_driver.create(db_name)
try:
- migrate(db_driver, db_name, migration_version)
+ _migrate(db_url, migration_version)
db_driver.dump(db_name, dump_filename)
finally:
db_driver.drop(db_name)
@@ -71,7 +88,7 @@ def diff_files(filename1, filename2):
### Database
-class MySQL(object):
+class Mysql(object):
def create(self, name):
subprocess.check_call(['mysqladmin', '-u', 'root', 'create', name])
@@ -83,11 +100,8 @@ class MySQL(object):
'mysqldump -u root %(name)s > %(dump_filename)s' % locals(),
shell=True)
- def url(self, name):
- return 'mysql://root@localhost/%s' % name
-
-class Postgres(object):
+class Postgresql(object):
def create(self, name):
subprocess.check_call(['createdb', name])
@@ -99,17 +113,12 @@ class Postgres(object):
'pg_dump %(name)s > %(dump_filename)s' % locals(),
shell=True)
- def url(self, name):
- return 'postgresql://localhost/%s' % name
-
-def _get_db_driver_class(db_type):
- if db_type == "mysql":
- return MySQL
- elif db_type == "postgres":
- return Postgres
- else:
- raise Exception(_("database %s not supported") % db_type)
+def _get_db_driver_class(db_url):
+ try:
+ return globals()[db_url.split('://')[0].capitalize()]
+ except KeyError:
+ raise Exception(_("database %s not supported") % db_url)
### Migrate
@@ -118,28 +127,28 @@ def _get_db_driver_class(db_type):
MIGRATE_REPO = os.path.join(os.getcwd(), "nova/db/sqlalchemy/migrate_repo")
-def migrate(db_driver, db_name, migration_version):
+def _migrate(db_url, migration_version):
earliest_version = _migrate_get_earliest_version()
# NOTE(sirp): sqlalchemy-migrate currently cannot handle the skipping of
# migration numbers.
_migrate_cmd(
- db_driver, db_name, 'version_control', str(earliest_version - 1))
+ db_url, 'version_control', str(earliest_version - 1))
upgrade_cmd = ['upgrade']
if migration_version != 'latest':
upgrade_cmd.append(str(migration_version))
- _migrate_cmd(db_driver, db_name, *upgrade_cmd)
+ _migrate_cmd(db_url, *upgrade_cmd)
-def _migrate_cmd(db_driver, db_name, *cmd):
+def _migrate_cmd(db_url, *cmd):
manage_py = os.path.join(MIGRATE_REPO, 'manage.py')
args = ['python', manage_py]
args += cmd
args += ['--repository=%s' % MIGRATE_REPO,
- '--url=%s' % db_driver.url(db_name)]
+ '--url=%s' % db_url]
subprocess.check_call(args)
@@ -200,7 +209,7 @@ def usage(msg=None):
print("ERROR: %s" % msg, file=sys.stderr)
prog = "schema_diff.py"
- args = ["<mysql|postgres>", "<orig-branch:orig-version>",
+ args = ["<db-url>", "<orig-branch:orig-version>",
"<new-branch:new-version>"]
print("usage: %s %s" % (prog, ' '.join(args)), file=sys.stderr)
@@ -209,9 +218,9 @@ def usage(msg=None):
def parse_options():
try:
- db_type = sys.argv[1]
+ db_url = sys.argv[1]
except IndexError:
- usage("must specify DB type")
+ usage("must specify DB connection url")
try:
orig_branch, orig_version = sys.argv[2].split(':')
@@ -223,7 +232,7 @@ def parse_options():
except IndexError:
usage('new branch and version required (e.g. master:82)')
- return db_type, orig_branch, orig_version, new_branch, new_version
+ return db_url, orig_branch, orig_version, new_branch, new_version
def main():
@@ -236,7 +245,7 @@ def main():
NEW_DUMP = NEW_DB + ".dump"
options = parse_options()
- db_type, orig_branch, orig_version, new_branch, new_version = options
+ db_url, orig_branch, orig_version, new_branch, new_version = options
# Since we're going to be switching branches, ensure user doesn't have any
# uncommited changes
@@ -244,18 +253,18 @@ def main():
die("You have uncommited changes. Please commit them before running "
"this command.")
- db_driver = _get_db_driver_class(db_type)()
+ db_driver = _get_db_driver_class(db_url)()
users_branch = git_current_branch_name()
git_checkout(orig_branch)
try:
# Dump Original Schema
- dump_db(db_driver, ORIG_DB, orig_version, ORIG_DUMP)
+ dump_db(db_driver, ORIG_DB, db_url, orig_version, ORIG_DUMP)
# Dump New Schema
git_checkout(new_branch)
- dump_db(db_driver, NEW_DB, new_version, NEW_DUMP)
+ dump_db(db_driver, NEW_DB, db_url, new_version, NEW_DUMP)
diff_files(ORIG_DUMP, NEW_DUMP)
finally: