FlaskでDBを使わずにWEBアプリを作る

webサービスを作り始めてっ感じたのは、db周りの開発が難しい。
元々、ドライバ開発者という事もあってdb周りはあんまり触ったことないのです。アンドロイドアプリのsqliteならまだわかるのですが、MySQLとか疎いです。

MySQLを学ぶというのもアリなんですが、それやっていると、いつまでたってもサイトが完成しないので、mySQLなど使うのはあきらめて、テキストファイルに保存して簡易DBを作ることにしました。

今のところDB書き込みは想定していないので、これで良しとします。

正直なところ、Kotlin+sparkjava等の寄り道せずに、さっさとPyCharmインストールしてpythonで開発すればよかったと思います。
pythonで予測変換できないのもPyCharm使ったら問題にならない使用感ですし・・・。

herokuのデプロイで動かない等、トラブルも多く動かすところまで持っていけなかったことを考えると、1ヶ月くらい無駄になった感じです。

自分のスキルなど

正直かなりの初心者なので、同じ初心者の方にはかなり参考になるのではないかと思います。

  • Python は実務で簡単なスクリプトを作成しただけの初心者
  • Flaskは初めて
  • WEBサービス作成は初めて
  • 開発環境
    • PyCharm CE
    • Python 3.8.2
    • Flask 1.1.2

やったこと要点

  • データ読み込み用のテキストファイルを準備
  • データ型のクラスを作成
  • ファイル読み込み処理を作成

参考サイト

FlaskでREST APIを作ってみる

データ読み込み用のテキストファイルを準備

僕が作ろうと思っているサイトはWEBサイトなので、データの書き込みに対応する必要はなく、読み込みが出来れば十分です。そこで、表示するデータは別にcsv形式のテキストファイルを用意して、データファイルを読み込ませてサイトに表示させます。

ただデータを読み込んでテンプレートに突っ込んでいるだけなので、データさえ準備すれば大量のページが簡単に作れるのが良いところですね。

なお、今回使用するデータは、国内ドラマ一覧になります。テキストファイルはとあるサイトをスクレイピングして作成していますが、作成方法については、別の記事で書こうと思います。

データ型のクラスを作成

ページ構成は、次のような3層構造を考えています。

  • ドメイン/title ⇒ 作品タイトル一覧
  • ドメイン/title/item_id ⇒ 作品毎のトップページ
  • ドメイン/title/item_id/episode ⇒ 作品のエピソード毎のページ

データ定義は次のようにしました。

  • titles.csv : 作品タイトル一覧
  • items.csv : 作品のエピソード一覧

作品タイトル一覧は、titles.csvから取得したリストを表示
作品毎のトップページは、items.csvからepisode == 0のデータを表示
作品のエピソード毎のページは、items.csvからepisode != 0のデータを表示

という具合になっています。

最初は、すべて同じファイルにしようと思っていたのですが、1レコードにページ内のすべてのデータを入れようと思ったので、作品一覧と各ページの表示を別のリストとしました。

まだ検討中なので、作っている過程で変更する可能性はあります。
なお、各レコードの具体的なデータ内容は以下です。

class VideoTitle:
    # ハッシュ化ID
    item_id: int
    # 作品タイトル
    title: str
    # 画像url
    img: str
class VideoItem:
    # ハッシュ化ID
    item_id: int
    # 作品タイトル
    title: str
    # オススメVOD
    recommend_vod: str = ""
    # 動画配信VOD
    unext: bool = False
    paravi: bool = False
    hulu: bool = False
    fod: bool = False
    # 第何話
    episode: int = 0

ファイル読み込み処理を作成

読み込むためのデータと、データフォーマットを示したクラスを作成したので、実際にファイルを読み取る処理を作成します。

エンコードをutf-8に指定してファイルをopenし、ファイルポインタを取得します。ファイルポインタから1行ずつreadして、改行コードを削除しカンマで分割。

VideoTitleクラスにしてvideo_titleに追加しています。video_titleはリストになっていて読み込み御終わった後は、video_titleの内容を返却する作りになっています。

with open('titles.csv', encoding='utf-8') as fp:
    for row in fp:
        line = row.replace('\r', '').replace('\n', '').split(',')
        video_title.append(
            VideoTitle(item_id=int(line[0]),
                       title=line[1],
                       img=line[2]))

作品毎のトップページや、エピソード毎のページの場合は、items.csvから読みだしてitem_idで絞り込んでいます。作品で絞り込むと、作品トップページにあたる0話から最終話まで取得できます。作品トップページは0話を使用して、各話はそれぞれのエピソードのデータを使ってページを作ります。

list(filter(lambda item: True if item.item_id == item_id else False, video_item))

参考サイト:

Jinja2の使い方がわかるとFlaskを用いた開発がよりスマートになる
[Flask/Jinja2]extendsやincludeを使い、メンテしやすいテンプレート構築を目指す

以上です。