diff options
author | Rick Harris <rconradharris@gmail.com> | 2013-11-01 20:13:30 +0000 |
---|---|---|
committer | Rick Harris <rconradharris@gmail.com> | 2013-11-01 21:13:16 +0000 |
commit | dcf7e4881c476ff7580a9e3131fb8e90032cf7f4 (patch) | |
tree | c7b63c3535f21b3b7d294ac70643cb86f6920126 /tools | |
parent | 4a50d64da43797b06b25c002d443e0686f324744 (diff) | |
download | nova-dcf7e4881c476ff7580a9e3131fb8e90032cf7f4.tar.gz |
Specify DB URL on command-line for schema_diff.py
The exising schema_diff code had the DB URL format hard-coded which made it
difficult to work with since different environments with have different
user/password configurations.
A more flexible way to handle this, is to have the DB URL specified directly
on the command-line.
Change-Id: I313bb616e439072e007c886a7f131efc6a61f6df
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/db/schema_diff.py | 71 |
1 files changed, 40 insertions, 31 deletions
diff --git a/tools/db/schema_diff.py b/tools/db/schema_diff.py index 99afd3d20f..b19d2fb4dd 100755 --- a/tools/db/schema_diff.py +++ b/tools/db/schema_diff.py @@ -24,12 +24,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 @@ -46,10 +58,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) @@ -74,7 +91,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]) @@ -86,11 +103,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]) @@ -102,17 +116,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 @@ -121,28 +130,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) @@ -203,7 +212,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) @@ -212,9 +221,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(':') @@ -226,7 +235,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(): @@ -239,7 +248,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 @@ -247,18 +256,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: |