質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

2回答

628閲覧

Docker環境でinit_appを実行できない

Nakano_Akito

総合スコア10

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

0クリップ

投稿2024/04/11 08:52

編集2024/04/12 04:50

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • 最初のレンダリング時にデータベースを構築(初期化)したい

前提

フロントエンドにVue(Vue3)を採用し、APIサーバであるFlaskを経由してデータを取得するというシステムを設計している。DBMSはSQLiteで、それをSQLAlchemyで操作している(ORM)。フロントで入力したデータをFlask経由でデータベースに登録する操作を実行したときにエラーが発生した。

発生している問題・エラーメッセージ

RuntimeError: The current Flask app is not registered with this 'SQLAlchemy' instance. Did you forget to call 'init_app', or did you create multiple 'SQLAlchemy' instances?

該当のソースコード

models.py

1from datetime import datetime 2from flask_sqlalchemy import SQLAlchemy 3 4db = SQLAlchemy() 5 6class Users(db.Model): 7 __tablename__ = 'users' 8 id = db.Column(db.Integer, primary_key=True) 9 name = db.Column(db.String(255)) 10 results = db.relationship('Results', backref='user', lazy=True) 11 12class Results(db.Model): 13 __tablename__ = 'results' 14 id = db.Column(db.Integer, primary_key=True) 15 user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) 16 level = db.Column(db.Text, nullable=False) 17 clearTime = db.Column(db.Integer, nullable=False) 18 collectedCoins = db.Column(db.Integer, nullable=False) 19 timestamp = db.Column(db.DateTime, index=True, default=datetime.now) 20 21def init_db(app): 22 db.init_app(app) 23 db.create_all() 24 25def add_user(name): 26 model = Users(name=name) 27 db.session.add(model) 28 db.session.commit()

app.py

1from flask import Flask, send_from_directory 2from api import api_bp 3from flask_sqlalchemy import SQLAlchemy 4from models import init_db 5 6app = Flask(__name__, static_folder='/usr/src/app/frontend/dist', static_url_path="") 7app.register_blueprint(api_bp) 8app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///maze.db' 9app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 10 11@app.route("/", defaults={'path': ''}) 12@app.route('/<path:path>') 13def index(path): 14 return send_from_directory(app.static_folder, "index.html") 15 16if __name__ == '__main__': 17 with app.app_context(): 18 init_db(app) 19 app.run()

docker

1services: 2 frontend: 3 build: 4 context: ./frontend 5 dockerfile: Dockerfile 6 command: npm run dev 7 ports: 8 - '5173:5173' 9 volumes: 10 - ./frontend:/usr/src/app 11 backend: 12 build: 13 context: ./backend 14 dockerfile: Dockerfile 15 ports: 16 - '5000:5000' 17 volumes: 18 - ./backend:/usr/src/app 19 - ./frontend/dist:/usr/src/app/frontend/dist 20 command: flask run --host=0.0.0.0

docker

1services: 2 frontend: 3 build: 4 context: ./frontend 5 dockerfile: Dockerfile 6 command: npm run dev 7 ports: 8 - '5173:5173' 9 volumes: 10 - ./frontend:/usr/src/app 11 backend: 12 build: 13 context: ./backend 14 dockerfile: Dockerfile 15 command: ["python3", "app.py", "--host=0.0.0.0"] 16 ports: 17 - '5000:5000' 18 volumes: 19 - ./backend:/usr/src/app 20 - ./frontend/dist:/usr/src/app/frontend/dist

backendの方のDockerfile

1FROM python:3.12.2 2 3WORKDIR /usr/src/app 4 5COPY ./ /usr/src/app/ 6COPY ./requirements.txt ./ 7 8RUN pip install --upgrade pip 9RUN pip install --upgrade flask 10RUN pip install -r requirements.txt 11RUN pip install flask_sqlalchemy 12RUN pip install flask-restful

試したこと

本アプリケーションとは異なるが、実環境でFlaskとVueを用いたWEBアプリケーションを作成したときは上記のコードでエラーは出なかった。CharGPT-4や各種Webサイトで調べたが、解決方法が見つからなかった。

補足情報(FW/ツールのバージョンなど)

特になし。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bsdfan

2024/04/12 00:21

どのようにDockerで実行しているかの情報が必要と思います。 実行したコマンドとオプション、docker compose 使っているなら yml ファイル、あとはどんなイメージを使っているかなど。 特に、sqlite を使われていますが、データの永続化の設定(ボリューム等)がちゃんとできているのかが気になりました。
Nakano_Akito

2024/04/12 01:27

ご指摘いただいたファイルを追加しました。 docker-compose.ymlにあるように、Docker環境を/usr/src/app/としています。
bsdfan

2024/04/12 02:25

flask run で実行されているので、db.init_app(app) の部分は実行されておらず、そのエラーになっているのではないでしょうか。(Docker以外の環境でエラーになっていないということなので、よくわからないところではありますが)
Nakano_Akito

2024/04/12 02:52

sqliteはファイルでDBを管理するので、コマンド操作は必要ないという認識でプロジェクトを進めていました(MySQLなどを利用する場合はdocker-compose.ymlにDB用のコンテナについての記述が必要?)。sqliteを使用する際のコマンド操作についての記事がありましたら、ご教示ください。自身で検索しましたが、見つけられませんでした...。
guest

回答2

0

ベストアンサー

質問文にあるコードを実行してみましたが、質問文にあるエラーメッセージは表示されませんでした。

質問文にある実行方法で実行されていないのかもしれません。(例えば、既に作成されているコンテナを実行していて、昔書いた部分が実行され、現在の手順が反映されていないなど)

また、bsdfanさんの指摘にもある通り、flask runでは、if __name__ == '__main__':部分が実行されないので、DBが作成される訳がありません。
Dockerfileの中で(例えばRUNで)、対象のコードを実行するようにするなど、手順を変えてみてはいかがでしょうか?
(if __name__ == '__main__':を動かすなら、python3 app.pyなどで実行する必要があります。)

それから、上記回答とは関係ありませんが、importされているflask-restfulは最終更新が2014年で、メンテナンスされていません。
これを使い続ける場合、セキュリティの問題や、新しいFlaskにバージョンアップされた時に動作しないなどの問題が発生する可能性があります。
FlaskにはClass-based Viewsという機能があります。
このページの下の方、Method Dispatching and APIsというあたりを参考にすると、flask-restfulを使わずにRESTful APIを実装可能です。

さらに余談ですが、現状はdevなので問題無いと思いますが、この構成のまま本番環境にデプロイしないよう注意ください。
本番環境ではflask runなどで実行される開発サーバの使用は推奨されていません。
FlaskをLinux環境で利用する場合はgunicornやmod-wsgi等を利用ください。

手前にWebサーバ(ApacheやNginx)を入れると良いです。

投稿2024/04/12 03:36

FiroProchainezo

総合スコア2421

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nakano_Akito

2024/04/12 04:16 編集

質問内容以外にもご指摘いただきありがとうございます。(flask runを実行)=(Flaskサーバ起動)という認識をしており、app.pyの実行についての知識が不十分であったため、今回のご指摘で大変勉強になりました。まずはDockerfileの修正、その後CRUD操作についての修正を行いたいと思います。 今後、分からないことが出てくると思います。その際は再びご指導ください。
Nakano_Akito

2024/04/12 04:49

DockerfileでRUNコマンドを記述するとDockerコンテナのビルド時にpython3 app.pyが実行され、ビルドが永遠に続いてしまいます。そこで、docker-compose.yml内のcommandプロパティでpython3 app.pyを記述しました。Dockerコンテナのビルド後、docker-composeを立ち上げましたが、localhostのアクセス制限に引っかかってしまいました。(この時、同様にinit_appが実行されていないというエラーが出力された。) 改変後のdocker-compose.ymlを本質問の編集として行いますので、記述方法が間違っていたらご指摘ください。
FiroProchainezo

2024/04/12 05:24

> DockerfileでRUNコマンドを記述するとDockerコンテナのビルド時にpython3 app.pyが実行され、ビルドが永遠に続いてしまいます。 buildが終わるように記載する必要があると思います。 たぶん、バックグラウンドで実行すれば終わってくれると思います。 回答では動くだろう方法を書きましたが、`docker run`(`docker-compose up`)する度にDBを作成(Sqliteなのでファイル作成)するのはおかしいかもしれません。 実行は `flask run` として、`docker exec -it {container name} bash`で中に入って、 `python3`からDBを作成するコマンドを実行するとか、 SqliteのDBファイルを作成するコマンドをローカルで実行し、 そのファイルをvolumeでマウントするような方法とかが良いかもしれません。 > docker-compose.yml内のcommandプロパティでpython3 app.pyを記述しました。Dockerコンテナのビルド後、docker-composeを立ち上げましたが、localhostのアクセス制限に引っかかってしまいました。 質問文にdocker-composeのような記述が2個ありますが、` command: ["python3", "app.py", "--host=0.0.0.0"]`がある方が最新ですか? `python3 app.py` は良いとして、`--host=0.0.0.0`は何でしょうか? `flask run --host=0.0.0.0`と同じで使っていますか? だとすると、`app.py`のどこかに`--host`オプションに対応する処理を追加する必要があります。 `argparse`とかを使うと楽だと思います。 (言い換えると、Nakano_Akitoさんの作成した`app.py`に`--host=0.0.0.0`を処理するコードは存在しません。 つまり、指定してもしなくても、指定しない場合と同じように動作し、`0.0.0.0`は指定されていないのと同じです。) オプション実装するのが面倒だったら、` app.run()`部分で指定してしまった方が楽です。
guest

0

以下の修正を行ったところ、DBの初期化に成功した。
・backendプロジェクトにおけるDockerfileで、「flask run」→「python3 app.py」に修正。
(そもそもPythonプロジェクト)

投稿2024/04/12 06:19

Nakano_Akito

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問