Skip to content

Commit

Permalink
Add migrations-graph helper script.
Browse files Browse the repository at this point in the history
  • Loading branch information
jezdez committed May 13, 2020
1 parent 7e90334 commit 0b7eac3
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
83 changes: 83 additions & 0 deletions bin/migrations-graph
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env python
"""
A quick helper script to print the Alembic migration history
via Graphiz and show it via GraphvizOnline on
https://dreampuf.github.io/GraphvizOnline/.
This requires the Graphviz Python library:
$ pip install --user graphviz
Then run it with the path to the Alembic config file:
$ migrations-graph --config migrations/alembic.ini
"""
import os
import sys
import urllib.parse
import urllib.request

import click
from alembic import util
from alembic.script import ScriptDirectory
from alembic.config import Config
from alembic.util import CommandError
from graphviz import Digraph

# Make sure redash can be imported in the migration files
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))


def get_revisions(config, rev_range=None):
script = ScriptDirectory.from_config(config)

if rev_range is not None:
if ":" not in rev_range:
raise util.CommandError(
"History range requires [start]:[end], [start]:, or :[end]"
)
base, head = rev_range.strip().split(":")
else:
base = head = None

return script.walk_revisions(base=base or "base", head=head or "heads")


def generate_revision_graph(revisions):
dot = Digraph()
for revision in revisions:
dot.node(revision.revision)
if revision.down_revision is None:
dot.edge("base", revision.revision)
continue
if isinstance(revision.down_revision, str):
dot.edge(revision.down_revision, revision.revision)
continue
for down_revision in revision.down_revision:
dot.edge(down_revision, revision.revision)
return dot


@click.command()
@click.option("--config", default="alembic.ini", help="path to alembic config file")
@click.option("--name", default="alembic", help="name of the alembic ini section")
def cli(config, name):
"""
Generates a simple Graphviz dot file and creates a link to
view it online via https://dreampuf.github.io/GraphvizOnline/.
"""
alembic_config = Config(file_=config, ini_section=name)
try:
revisions = get_revisions(alembic_config)
except CommandError as e:
sys.exit(e)

dot = generate_revision_graph(revisions)
encoded_dot = urllib.parse.quote(bytes(dot.source, "utf-8"))
viz_url = "https://dreampuf.github.io/GraphvizOnline/#%s" % encoded_dot
print("Generated graph for migration history in %s: %s " % (config, viz_url))


if __name__ == "__main__":
cli()
1 change: 1 addition & 0 deletions migrations/alembic.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# A generic, single database configuration.

[alembic]
script_location = migrations
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s

Expand Down

0 comments on commit 0b7eac3

Please sign in to comment.