💬

AIを利用して知識ゼロからPythonでシステム構築をする その3 - 構築失敗編 -

2023/09/04に公開

構築失敗編

前提知識と仕様

  • PHPやJavaを用いたWebアプリケーションの開発経験はあるが、Pythonは全く触った経験無し
  • さくらのレンタルサーバ スタンダードを契約済み
  • 問い合わせは基本的に無料で利用できるChatGPT3.5を利用
  • できる限りAIを利用して構築(使用技術等は自分で決定し、随時記載)
  • フレームワークはFlaskを使ってみることとする

User

Flaskを利用してデータベースと接続するWebアプリを作成したい

ChatGPT

素晴らしいです!Flaskを使用してデータベースと接続するWebアプリケーションを作成することは、一般的なタスクです。以下に、基本的な手順とコードの例を示します。

  1. Flaskのインストール:
    Flaskを使用するには、まずPythonパッケージマネージャー(pip)を使用してFlaskをインストールする必要があります。ターミナルまたはコマンドプロンプトで以下のコマンドを実行します。

    pip install flask
    
  2. 必要なモジュールをインポートする:
    Flaskと必要なモジュールをPythonファイルにインポートします。

    from flask import Flask, render_template, request
    from flask_sqlalchemy import SQLAlchemy
    
  3. Flaskアプリケーションを設定する:
    Flaskアプリケーションを作成し、データベースの接続情報を設定します。

    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'データベースの接続URL'
    db = SQLAlchemy(app)
    
  4. データベースモデルを定義する:
    データベース内のテーブルを表すモデルを作成します。これには、データベーステーブルの各列をモデルの属性として定義する必要があります。

    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))
    
        def __init__(self, name):
            self.name = name
    
  5. ルートとビューを作成する:
    Flaskアプリケーションのルート(URLパス)とビュー(関数)を作成します。以下は、データベースからユーザーのリストを取得してテンプレートに渡す例です。

    @app.route('/')
    def index():
        users = User.query.all()
        return render_template('index.html', users=users)
    
  6. テンプレートを作成する:
    ビューから受け取ったデータを表示するためのHTMLテンプレートを作成します。

    <!DOCTYPE html>
    <html>
    <head>
        <title>Users</title>
    </head>
    <body>
        <h1>User List</h1>
        <ul>
            {% for user in users %}
            <li>{{ user.name }}</li>
            {% endfor %}
        </ul>
    </body>
    </html>
    
  7. アプリケーションを実行する:
    Flaskアプリケーションを実行するために、Pythonファイルの最後に以下のコードを追加します。

    if __name__ == '__main__':
        app.run()
    

これらの手順に従って、Flaskを使用してデータベースと接続するWebアプリケーションを作成できます。ただし、データベースの種類によっては、追加の設定やモジュールが必要になる場合があります。また、データベースへの接続情報やモデルの定義など、具体的な詳細は、使用するデータベースの種類に依存します。


データベースの接続URLがわからないので問い合わせ


User

データベースの接続URLとはどんなものですか?

ChatGPT

データベースの接続URLは、使用するデータベースの種類によって異なります。一般的なデータベースの接続URLの形式をいくつか説明します。

  1. SQLiteの場合:
    SQLiteデータベースを使用する場合、接続URLは単純なファイルパスです。

    sqlite:///path/to/database.db
    

    ここで、/path/to/database.dbはSQLiteデータベースファイルのパスです。

  2. MySQLの場合:
    MySQLデータベースを使用する場合、接続URLは次のような形式になります。

    mysql://ユーザー名:パスワード@ホスト名:ポート/データベース名
    

    例えば、ユーザー名がroot、パスワードがpassword、ホストがlocalhost、ポートがデフォルトの3306である場合は、以下のようになります。

    mysql://root:password@localhost:3306/mydatabase
    
  3. PostgreSQLの場合:
    PostgreSQLデータベースを使用する場合、接続URLは次のような形式になります。

    postgresql://ユーザー名:パスワード@ホスト名:ポート/データベース名
    

    例えば、ユーザー名がmyuser、パスワードがmypassword、ホストがlocalhost、ポートがデフォルトの5432である場合は、以下のようになります。

    postgresql://myuser:mypassword@localhost:5432/mydatabase
    

これらは一般的なデータベースの接続URLの例ですが、実際の接続URLは使用しているデータベースの種類や設定によって異なります。具体的なデータベースのドキュメントや設定に基づいて、適切な接続URLを使用してください。


データベースモデルを定義するとあるが、実際にはどこに定義すべきかわからないので問い合わせ


User

データベースモデルはどこに定義すればいいですか?
app.pyですか?それとも別のファイルを作成して定義しますか?

ChatGPT

データベースモデルを定義する場所については、プロジェクトの構造や好みによります。一般的なアプローチは、モデルを別のファイルに作成して定義することです。

以下に、モデルを別のファイルに作成する方法の例を示します。

  1. プロジェクトの構造:
    まず、プロジェクトの構造を作成します。一般的な構造は次のようなものです。

    ├── app.py
    ├── models.py
    ├── templates/
    │   └── ...
    ├── static/
    │   └── ...
    └── ...
    

    app.pyはFlaskアプリケーションのエントリーポイントであり、models.pyはデータベースモデルの定義ファイルです。

  2. models.pyにモデルを定義する:
    models.pyファイルを作成し、データベースモデルを定義します。以下は例です。

    from flask_sqlalchemy import SQLAlchemy
    
    db = SQLAlchemy()
    
    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))
    
        def __init__(self, name):
            self.name = name
    

    models.pyでは、必要なモジュールをインポートしてデータベースオブジェクト(db)を作成し、その下にデータベースモデルを定義します。

  3. app.pyでモデルを使用する:
    app.pyファイルで、models.pyで定義したモデルを使用するためにインポートします。

    from flask import Flask, render_template, request
    from models import db, User
    
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'データベースの接続URL'
    db.init_app(app)
    
    # ルートやビューの定義など、アプリケーションの残りの部分
    

    models.pyから必要なモデルやデータベースオブジェクトをインポートし、db.init_app(app)でアプリケーションとデータベースを関連付けます。

このようにすることで、データベースモデルをmodels.pyファイルに分離し、app.pyファイルでそれを使用することができます。ただし、プロジェクトの要件や規模に応じて、モデルの定義を1つのファイルにまとめる方法や、パッケージとしてモデルを管理する方法など、さまざまなアプローチがあります。プロジェクトに最適なアーキテクチャを選択してください。


SQLAlchemyというものを使ってデータベースを操作するようだが、SQLAlchemyがどういうものかわからないので問い合わせ


User

SQLAlchemyとは何ですか?

ChatGPT

SQLAlchemyは、Pythonのデータベースアクセスライブラリであり、リレーショナルデータベースを操作するための高水準なAPIを提供します。SQLAlchemyは、データベースに対して直接SQLクエリを実行するだけでなく、オブジェクトリレーショナルマッピング(ORM)の機能を提供することで、データベースとのやり取りを簡素化します。

SQLAlchemyの主な特徴と利点は次のとおりです:

  1. ORMサポート: SQLAlchemyはORMを提供し、データベーステーブルをPythonクラスとしてモデル化することができます。モデルクラスのインスタンスを作成し、それらをデータベースに保存、取得、更新、削除することができます。ORMにより、SQLを直接書かずにPythonオブジェクトを操作することができます。

  2. データベース間のポータビリティ: SQLAlchemyは、異なるリレーショナルデータベースシステム(例: SQLite、MySQL、PostgreSQL)の間でコードの再利用を可能にするため、データベース間の移植性を向上させます。データベースの接続URLを変更するだけで、異なるデータベースシステムを使用することができます。

  3. データベースクエリの柔軟性: SQLAlchemyは、SQLを直接書くこともできます。高度なクエリを作成し、データベースのテーブルや関連するデータを操作するための柔軟なインターフェースを提供します。また、データベース固有のSQL構文や機能を直接使用することもできます。

  4. トランザクションのサポート: SQLAlchemyはトランザクションの管理もサポートしており、複数のデータベース操作をグループ化し、アトミックな操作として処理することができます。トランザクションの開始、コミット、ロールバックなどの操作を簡単に実行できます。

  5. パフォーマンスの最適化: SQLAlchemyは、データベースクエリの効率的な実行とパフォーマンスの最適化にも取り組んでいます。クエリ結果のキャッシング、遅延ロード、インデックスの最適化などの機能を提供しています。

SQLAlchemyは人気のあるデータベースライブラリであり、多くの開発者によって利用されています。Flaskと組み合わせることで、Webアプリケーションのデータベース操作を簡単かつ柔軟に行うことができます。


追加仕様

  • データベースはsqliteを利用
  • データベースライブラリはSQLAlchemyを利用

User

Flask でデータベースはsqliteを利用をしたい。
SQLAlchemyを使う場合、どう書けばいいですか?

ChatGPT

FlaskでSQLiteを使用する場合にSQLAlchemyを組み合わせる方法を説明します。

  1. 必要なモジュールをインポートする:
    FlaskとSQLAlchemyモジュールをPythonファイルにインポートします。

    from flask import Flask, render_template
    from flask_sqlalchemy import SQLAlchemy
    
  2. Flaskアプリケーションを作成する:
    Flaskアプリケーションを作成します。

    app = Flask(__name__)
    
  3. データベースの設定を行う:
    SQLAlchemyを使用するために、データベースの接続URLとしてSQLiteのパスを設定します。

    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
    db = SQLAlchemy(app)
    

    上記の例では、データベースファイル名をdatabase.dbとしています。適切なデータベースファイルのパスに置き換えてください。

  4. モデルを定義する:
    SQLAlchemyを使用してデータベースモデルを定義します。

    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))
    

    ここで、Userというモデルを作成し、idnameの2つのカラムを定義しています。

  5. ルートとビューを作成する:
    Flaskアプリケーションのルート(URLパス)とビュー(関数)を作成します。

    @app.route('/')
    def index():
        users = User.query.all()
        return render_template('index.html', users=users)
    

    ここでは、Userモデルのすべてのデータを取得し、それをテンプレートに渡しています。

  6. アプリケーションを実行する:
    Flaskアプリケーションを実行するために、Pythonファイルの最後に以下のコードを追加します。

    if __name__ == '__main__':
        app.run()
    

これらの手順に従って、FlaskでSQLiteデータベースを使用し、SQLAlchemyを組み合わせたWebアプリケーションを作成できます。SQLAlchemyを使用することで、より高度なデータベース操作やクエリの作成などを行うことができます。また、データベースファイルのパスやモデルの定義など、具体的な詳細はプロジェクトの要件に応じて適宜変更してください。


問題発生

500 エラーになるが原因がわからない。
1つずつコメントアウトしていくとfrom models import db, Userに問題あり
models.pyが悪いことがわかるが何が悪いかわからないのではじめから問い合わせ


User

flaskを利用してCRUDのアプリケーションを作成したい。
models.pyにテーブル定義を書く場合、どのように書きますか?

ChatGPT

Flaskでは、データベースのテーブル定義を行うために通常、ORM(Object-Relational Mapping)ライブラリを使用します。ORMを使用することで、Pythonのコードを使ってデータベースのテーブルを定義したり操作したりすることができます。

以下は、Flask SQLAlchemyというORMライブラリを使用して、テーブル定義を行う例です。

  1. まず、Flask SQLAlchemyをインストールします。ターミナルまたはコマンドプロンプトで以下のコマンドを実行します。
pip install flask-sqlalchemy
  1. Flaskアプリケーションのルートディレクトリに、models.pyという名前のファイルを作成します。

  2. models.pyファイル内で、必要なモジュールをインポートします。

from flask_sqlalchemy import SQLAlchemy
from flask import Flask

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'データベースの接続情報'  # データベースの接続情報を指定します
db = SQLAlchemy(app)
  1. テーブルを定義するためのクラスを作成します。以下は、Userテーブルの例です。
class User(db.Model):
    __tablename__ = 'users'  # テーブル名を指定します

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    email = db.Column(db.String(50))

    def __init__(self, name, email):
        self.name = name
        self.email = email

上記の例では、Userクラスがdb.Modelを継承しています。クラスの属性はテーブルのカラムを表し、db.Columnの引数にカラムのデータ型や制約を指定します。__init__メソッドは、新しいレコードを作成する際に使用されるコンストラクタです。

  1. テーブルの作成やマイグレーションなど、データベースの操作を行うためのコマンドを実行するためのスクリプトを作成します。通常、Flaskのコマンドラインインターフェースを使用して行います。例えば、以下のようなmanage.pyファイルを作成します。
from flask_script import Manager
from your_app import app, db

manager = Manager(app)

@manager.command
def create_tables():
    db.create_all()

if __name__ == '__main__':
    manager.run()

上記の例では、create_tablesというコマンドを作成しています。このコマンドを実行すると、db.create_all()メソッドが呼び出されて、定義したテーブルがデータベースに作成されます


そもそもpip install flask-sqlalchemyをした覚えがないのでこれが原因では?

% pip install flask-sqlalchemy
Collecting flask-sqlalchemy
  Downloading flask_sqlalchemy-3.0.5-py3-none-any.whl (24 kB)
Requirement already satisfied: flask>=2.2.5 in /home/XXX/.pyenv/versions/3.9.6/envs/3.9.6-flask/lib/python3.9/site-packages (from flask-sqlalchemy) (2.3.2)
Collecting sqlalchemy>=1.4.18 (from flask-sqlalchemy)
  Downloading SQLAlchemy-2.0.17-py3-none-any.whl (1.8 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 31.6 MB/s eta 0:00:00
Requirement already satisfied: Werkzeug>=2.3.3 in /home/XXX/.pyenv/versions/3.9.6/envs/3.9.6-flask/lib/python3.9/site-packages (from flask>=2.2.5->flask-sqlalchemy) (2.3.6)
Requirement already satisfied: Jinja2>=3.1.2 in /home/XXX/.pyenv/versions/3.9.6/envs/3.9.6-flask/lib/python3.9/site-packages (from flask>=2.2.5->flask-sqlalchemy) (3.1.2)
Requirement already satisfied: itsdangerous>=2.1.2 in /home/XXX/.pyenv/versions/3.9.6/envs/3.9.6-flask/lib/python3.9/site-packages (from flask>=2.2.5->flask-sqlalchemy) (2.1.2)
Requirement already satisfied: click>=8.1.3 in /home/XXX/.pyenv/versions/3.9.6/envs/3.9.6-flask/lib/python3.9/site-packages (from flask>=2.2.5->flask-sqlalchemy) (8.1.3)
Requirement already satisfied: blinker>=1.6.2 in /home/XXX/.pyenv/versions/3.9.6/envs/3.9.6-flask/lib/python3.9/site-packages (from flask>=2.2.5->flask-sqlalchemy) (1.6.2)
Requirement already satisfied: importlib-metadata>=3.6.0 in /home/XXX/.pyenv/versions/3.9.6/envs/3.9.6-flask/lib/python3.9/site-packages (from flask>=2.2.5->flask-sqlalchemy) (6.7.0)
Collecting typing-extensions>=4.2.0 (from sqlalchemy>=1.4.18->flask-sqlalchemy)
  Downloading typing_extensions-4.7.0-py3-none-any.whl (33 kB)
Collecting greenlet!=0.4.17 (from sqlalchemy>=1.4.18->flask-sqlalchemy)
  Downloading greenlet-2.0.2.tar.gz (164 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 165.0/165.0 kB 46.0 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: zipp>=0.5 in /home/XXX/.pyenv/versions/3.9.6/envs/3.9.6-flask/lib/python3.9/site-packages (from importlib-metadata>=3.6.0->flask>=2.2.5->flask-sqlalchemy) (3.15.0)
Requirement already satisfied: MarkupSafe>=2.0 in /home/XXX/.pyenv/versions/3.9.6/envs/3.9.6-flask/lib/python3.9/site-packages (from Jinja2>=3.1.2->flask>=2.2.5->flask-sqlalchemy) (2.1.3)
Building wheels for collected packages: greenlet
  Building wheel for greenlet (pyproject.toml) ... done
  Created wheel for greenlet: filename=greenlet-2.0.2-cp39-cp39-freebsd_13_0_release_p13_amd64.whl size=611345 sha256=ed2d0b31959ab6fdfbf7aa506f12ea03054162cf0f87fef3e6066be581004a5c
  Stored in directory: /home/XXX/.cache/pip/wheels/c4/e2/38/932349e5e893e6d464ea70f98f76a8d7b9ba73e62cc9db5579
Successfully built greenlet
Installing collected packages: typing-extensions, greenlet, sqlalchemy, flask-sqlalchemy
Successfully installed flask-sqlalchemy-3.0.5 greenlet-2.0.2 sqlalchemy-2.0.17 typing-extensions-4.7.0

from models import db, Userでエラーにはならなくなったが、別の500エラーが発生。
ログを確認するとAH01215: sqlite3.OperationalError: no such table: user: というメッセージを発見。
どうやら自動でテーブルは作ってくれないらしい。
manage.pyのようなファイルを作成して自分で実行しないといけないらしい。
サンプルのfrom your_app import app, dbからyour_appとは?という疑問が発生したので問い合わせ


User

your_appとは具体的にどのファイルですか?

ChatGPT

your_appは、具体的なファイル名やディレクトリ名ではなく、抽象的なアプリケーション名を表しています。この名前は、実際のプロジェクトやアプリケーションの名前に置き換える必要があります。

your_appという表記は、コードの一部として説明や例示をする際に一般的に使用されるプレースホルダーです。実際のアプリケーション名やプロジェクト構造に合わせて、適切な名前に置き換えてください。

例えば、プロジェクトのディレクトリ構造が以下のような場合を考えます:

your_project/
    your_app/
        __init__.py
        models.py
        manage.py
    config.py

この場合、your_appyour_projectディレクトリ内のアプリケーションディレクトリを指します。したがって、具体的なファイルパスに置き換えると以下のようになります。

  • your_app/__init__.py
  • your_app/models.py
  • your_app/manage.py

したがって、from your_app import app, dbという記述は、your_appディレクトリ内の__init__.pyファイルで定義されているappdbオブジェクトをインポートしていることを意味します。

your_appは、具体的なアプリケーション名やプロジェクト名に置き換える必要があります。実際のファイルパスやディレクトリ構造に合わせて、適切な名前を使用してください。


今回のプロジェクトでは具体的なアプリケーション名はまだ決まっていないのと一般的なディレクトリ構造がわからないので問い合わせ


User

flaskを用いたアプリケーションの一般的なディレクトリ構造はどうなりますか?

ChatGPT

Flaskを使用したアプリケーションの一般的なディレクトリ構造は、以下のような形になります。

your_project/
    your_app/
        __init__.py
        models.py
        views.py
        templates/
            index.html
            ...
        static/
            css/
                style.css
            js/
                script.js
            images/
                ...
    config.py
    manage.py

上記のディレクトリ構造は一般的な形式であり、プロジェクトの規模や要件によって変化する可能性があります。基本的な構造は以下の通りです。

  • your_project/: プロジェクトのルートディレクトリ。
  • your_app/: アプリケーションのディレクトリ。
    • __init__.py: アプリケーションのエントリポイントであり、Flaskアプリケーションオブジェクトが作成される場所。
    • models.py: データベースのモデルやテーブル定義など、データベース関連のコードが格納される場所。
    • views.py: アプリケーションのビューロジック(ルーティング、リクエスト処理など)が定義される場所。
    • templates/: HTMLテンプレートファイルが格納されるディレクトリ。
    • static/: 静的ファイル(CSS、JavaScript、画像など)が格納されるディレクトリ。
  • config.py: アプリケーションの設定ファイルが置かれる場所。
  • manage.py: アプリケーションの管理スクリプト。アプリケーションの起動やデータベースのマイグレーションなどを実行するためのコマンドが記述されます。

このディレクトリ構造は一般的なガイドラインであり、特定のプロジェクトや要件に合わせてカスタマイズすることができます。プロジェクトが成長し、追加の機能やモジュールが必要になる場合は、適切なディレクトリを追加するなど、ディレクトリ構造を柔軟に変更することができます。


今まで作ってきたapp.pyがないのでこれをどうすればいいのか?問い合わせ


User

app.pyは不要ですか?

ChatGPT

app.pyは、Flaskアプリケーションのエントリポイントとして使用される一般的なファイル名の1つです。app.pyは、FlaskのFlaskオブジェクトを作成し、アプリケーションの設定やルーティングを定義する役割を果たします。

しかし、app.pyの使用は必須ではありません。app.py以外のファイル名(例:main.pyrun.pyなど)を使用しても問題ありません。重要なのは、アプリケーションのエントリポイントファイルであることです。

一般的なディレクトリ構造では、app.pyという名前のファイルを使用することが多いですが、プロジェクトによっては別のファイル名を使用することもあります。

例えば、以下のようなディレクトリ構造を考えてみましょう。

your_project/
    main.py
    your_app/
        __init__.py
        models.py
        views.py
        templates/
            index.html
        static/
            css/
                style.css
            js/
                script.js
            images/
                ...
    config.py
    manage.py

上記の場合、main.pyファイルがアプリケーションのエントリポイントとなります。main.pyファイル内でFlaskのFlaskオブジェクトを作成し、アプリケーションの設定やルーティングを定義します。

短い回答としては、app.pyは一般的なファイル名ですが、必須ではありません。他のファイル名を使用してもかまいません。重要なのは、アプリケーションのエントリポイントファイルを適切に作成することです。


ここまでディレクトリ構成について問い合わせてきたが、ここでGoogle先生にも聞くことにする。
例えば「flask ディレクトリ構成 ベストプラクティス」で問い合わせると
Flaskのフォルダ構成をまとめた【Flask】ディレクトリ構成を考える
など、ちょっと違うディレクトリ構成が出てくる。

さらに色々と調べたところで基礎的なものがわからない状態で開発を続けるには限界があり、逆に時間を無駄にしていると認識。
ドキュメントチュートリアルを読んで勉強するほうが早いと感じる

また、Pythonの基礎知識もつけるべきであり、例えば東大が無料で公開しているPythonプログラミング入門や無料で公開されているハーバード大学のPythonの講義(日本語字幕付き)などを勉強しなければいけない

Discussion