From 2d673b16cd74872796f3e4cd51867ba2478025e3 Mon Sep 17 00:00:00 2001 From: karen chan Date: Fri, 20 Oct 2017 10:28:54 -0700 Subject: [PATCH] Add `--sort` (version or applied) to `dbmigrator list` `dbmigrator list` only shows migrations in the order of migration filenames at the moment. It works well for when users are trying to migrate. When users are trying to rollback however, it is difficult to tell which migration will be rolled back because the applied dates are not in the same order as the migration filenames. This change allows the user to specify the order by doing `--sort=applied`: ``` version | name | is applied | date applied ---------------------------------------------------------------------- 20160228212456 cool_stuff True 2017-10-20 10:27:57.011677-07:00 20160228202637 add_table False ``` --- dbmigrator/commands/list.py | 19 +++++++++++++------ dbmigrator/tests/test_cli.py | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/dbmigrator/commands/list.py b/dbmigrator/commands/list.py index 0e0a623..66d3eb9 100644 --- a/dbmigrator/commands/list.py +++ b/dbmigrator/commands/list.py @@ -16,7 +16,7 @@ @utils.with_cursor def cli_command(cursor, migrations_directory='', db_connection_string='', - wide=False, **kwargs): + wide=False, sort='version', **kwargs): # version -> applied timestamp migrated_versions = dict(list( utils.get_schema_versions(cursor, versions_only=False, @@ -35,22 +35,29 @@ def cli_command(cursor, migrations_directory='', db_connection_string='', .format(name_format.format('name'))) print('-' * 70) + migrations = [(version, migration_name, migration, + migrated_versions.get(version, '')) + for version, migration_name, migration in migrations] + if sort == 'applied': + migrations.sort(key=lambda a: str(a[-1]) or 'None') + name_format = '{: <%s}' % (name_width,) - for version, migration_name, migration in migrations: - applied_timestamp = migrated_versions.get(version, '') + for version, migration_name, migration, applied_timestamp in migrations: deferred = utils.is_deferred( version, migration, migrated_versions) - is_applied = deferred and 'deferred' or \ - bool(migrated_versions.get(version)) + is_applied = deferred and 'deferred' or bool(applied_timestamp) if hasattr(migration, 'should_run'): is_applied = '{}*'.format(is_applied) print('{} {} {!s: <10} {}'.format( version, name_format.format(migration_name[:name_width]), - is_applied, migrated_versions.get(version) or '')) + is_applied, applied_timestamp)) def cli_loader(parser): parser.add_argument('--wide', action='store_true', dest='wide', default=False, help='Display the full name of every migration') + parser.add_argument( + '--sort', default='version', choices=['version', 'applied'], + help='Sort by migration "version" (default), or "applied" dates') return cli_command diff --git a/dbmigrator/tests/test_cli.py b/dbmigrator/tests/test_cli.py index d21a8e7..0461a57 100644 --- a/dbmigrator/tests/test_cli.py +++ b/dbmigrator/tests/test_cli.py @@ -144,6 +144,30 @@ def test_wide(self): \n""", stdout) self.assertEqual('', stderr) + def test_sort_applied(self): + testing.install_test_packages() + + cmd = ['--db-connection-string', testing.db_connection_string] + self.target(cmd + ['init']) + self.target(cmd + ['--context', 'package-a', + 'mark', '-t', '20160228212456']) + with testing.captured_output() as (out, err): + self.target(cmd + ['--context', 'package-a', 'list', + '--sort=applied']) + + stdout = out.getvalue() + stderr = err.getvalue() + + applied_timestamp = ' '.join(stdout.split()[13:15]) + self.assertEqual("""\ +version | name | is applied | date applied +---------------------------------------------------------------------- +20160228212456 cool_stuff True {} +20160228202637 add_table False \ +\n""".format(applied_timestamp), stdout) + + self.assertEqual('', stderr) + class InitTestCase(BaseTestCase): def test_multiple_contexts(self):