Skip to content

Commit

Permalink
Add --sort (version or applied) to dbmigrator list
Browse files Browse the repository at this point in the history
`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
```
  • Loading branch information
karenc committed Oct 20, 2017
1 parent 0333632 commit 2d673b1
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
19 changes: 13 additions & 6 deletions dbmigrator/commands/list.py
Expand Up @@ -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,
Expand All @@ -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
24 changes: 24 additions & 0 deletions dbmigrator/tests/test_cli.py
Expand Up @@ -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):
Expand Down

0 comments on commit 2d673b1

Please sign in to comment.