Python+Flaskでテーブル定義書を自動生成するWebアプリケーションを作ってみた

  • 4
    Like
  • 0
    Comment

概要

データベースのテーブル定義書を自動的に生成して、ブラウザ上で確認できるWebアプリケーションを作成しました。自動生成によって、テーブル定義が更新されたときに、手動でドキュメントを更新する手間を省きます。もちろん、このWebアプリケーションは、アクセスが限定された場所で動かすことを想定しています。

ただし、今回作成したWebアプリケーションはMySQL、MariaDBにしか対応していません。

ソースコードの方はGitHubで公開しています。

画面例

テーブル一覧

スクリーンショット 2017-10-16 5.58.17.png

テーブル名をクリックすると、そのテーブルの定義書のページに飛びます。

テーブル定義書

スクリーンショット 2017-10-16 5.56.10.png

テーブル情報、カラム一覧、キー一覧、外部キー一覧が表示されます。

開発環境

使用したプログラミング言語はPython3で、WebフレームワークはFlaskです。今回作るのは小規模なWebアプリケーションなので、お手軽に作れるFlaskを使用しました。

データベースは冒頭でも言った通り、MySQLかMariaDBです。information_schemaのテーブルから情報を取得するのですが、ORMを使わず、mysql-connector-python-rfを使って、生SQLで情報を取得しています(いずれORMを使うようにしたい)。

どういう処理をしているのか

Flaskの基本的な使い方は、Flask本家のドキュメントを参照してください。

今回作ったアプリケーションでやっているのは基本的にこれだけです。
- SQLでselectを実行しfetchする
- fetchした内容をtemplateに渡す

テーブル一覧画面の場合

テーブル一覧画面を例にして説明します。

Pythonコード

Pythonのコードは次のようになります。

@app.route('/db/<schema_name>/')
def show_tables(schema_name):
    # SQLを実行し、select結果をfetch
    cursor = connection.cursor(buffered=True, dictionary=True)
    cursor.execute(select_tables, {'schema': schema_name})
    tables = cursor.fetchall()
    cursor.close()

    # fetchした結果をtemplate 'tables.html' に渡す
    return render_template(
        'tables.html',
        schema=schema_name,
        tables=tables
    )

connectionはデータベース接続オブジェクトのインスタンスで、mysql.connector.connect関数で生成しています。データベースはinformation_schemaを参照しています。

select_tablesはSQLステートメントの文字列で、中身は次のようになります。%(schema)sは、bind parameterです。

SELECT
  table_name,
  engine,
  table_rows,
  table_collation,
  create_time,
  update_time,
  table_comment
FROM
  tables
WHERE
  table_schema = %(schema)s

cursorのインスタンス生成でdictionary=Trueとしているのは、各レコードを辞書形式で扱うためです。例えば、tables[0]['table_name']で、0行目のtable_nameカラムの値にアクセスできます。

htmlテンプレート

Python側から渡された変数は、htmlテンプレート側では次のように処理しています。for文を回して、データを取り出しているだけです。

<table border="1">
    <tr>
        <th>name</th>
        <th>engine</th>
        <th>rows</th>
        <th>collation</th>
        <th>create time</th>
        <th>update time</th>
        <th>comment</th>
    </tr>
    {% for tb in tables %}
    <tr>
        <td><a href="{{ tb['table_name'] }}">{{ tb['table_name'] }}</a></td>
        <td>{{ tb['engine'] }}</td>
        <td>{{ tb['table_rows'] }}</td>
        <td>{{ tb['table_collation'] }}</td>
        <td>{{ tb['create_time'] }}</td>
        <td>{{ tb['update_time'] }}</td>
        <td>{{ tb['table_comment'] }}</td>
    </tr>
    {% endfor %}
</table>

最後に

冒頭でも言った通りソースコードを公開していますので、何か問題点や改善点があれば、コメントをよろしくお願いします。