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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1422閲覧

FlaskでBlueprintを利用した際、application context外でconfigを読み込む方法

MagMag

総合スコア80

Flask

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/02/15 02:47

編集2023/02/15 08:19

実現

  • Python+Flaskでwebアプリケーションを作りたい
  • 機能が増えてきたので、Blueprintでviewを分割したい
  • DBはDynamoDBと連携しており、pynamodbというpythonでDBを操作できるライブラリを利用。この中では、application.configを読み込みたい。

困っていること・状況

  • Blueprintで分割した時、DBテーブル設定におけるコンフィグを読めない
  • 実行結果より、current_appがapplication context外で読まれていることが原因であることはわかるが、具体的にうまく読ませる方法がわかりません。
  • 例えば、class Metaの内部をwith application.app_context()で囲むことも行ったが、「AttributeError: As of v1.0 PynamoDB Models must have a table_name」とエラーが返ってくる(クラス変数を適切に取得できていない?)
  • 関数(obtain_data)の中でclassを定義すると問題なく読み込むが、コードが重複するので避けたい

質問

  • Blueprintでモジュール分割した場合にapplication context外で設定を読み込む方法を教えていただきたい

動いているコード

Python

1from flask import Flask, current_app 2from pynamodb.models import Model 3from pynamodb.attributes import UnicodeAttribute 4 5application = Flask(__name__) 6 7class DB(Model): 8 class Meta: 9 table_name = application.config.get('TABLE') 10 region = application.config.get('AWS_REGION') 11 aws_access_key_id = application.config.get('AWS_ACCESS_KEY_ID') 12 aws_secret_access_key = application.config.get('AWS_SECRET_ACCESS_KEY') 13 14 partition_key = UnicodeAttribute(hash_key=True, null=False) 15 data = UnicodeAttribute(null=True) 16 17@application.route('/obtain_dada/<partition_key>') 18def obtain_data(partition_key): 19 entries = DB.scan(partition_key) 20 entries = sorted(entries, key=lambda x: x.partition_key, reverse=True) 21 return entries

動かないコード

Python

1from flask import Flask, current_app 2from pynamodb.models import Model 3from pynamodb.attributes import UnicodeAttribute 4 5application = Flask(__name__) 6sub = Blueprint('sub', __name__) 7application.register_blueprint(sub) 8 9class DB(Model): 10 class Meta: 11 table_name = current_app.config.get('TABLE') 12 region = current_app.config.get('AWS_REGION') 13 aws_access_key_id = current_app.config.get('AWS_ACCESS_KEY_ID') 14 aws_secret_access_key = current_app.config.get('AWS_SECRET_ACCESS_KEY') 15 16 partition_key = UnicodeAttribute(hash_key=True, null=False) 17 data = UnicodeAttribute(null=True) 18 19@sub.route('/obtain_dada/<partition_key>') 20def obtain_data(partition_key): 21 entries = DB.scan(partition_key) 22 entries = sorted(entries, key=lambda x: x.partition_key, reverse=True) 23 return entries

実行結果

flask runして/obtain_dataにアクセスした結果
"This typically means that you attempted to use functionality that needed to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the documentation for more information."

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

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

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

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

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

quickquip

2023/02/15 03:39

動かないコードの方での、Flaskの初期化やregister_blueprintのコードはどうなっているかが必要そうです。 あと、エラーが出るのが何をした時かが書かれてないと思いました。該当のBlueprintのURLにアクセスした時で合ってますか。
MagMag

2023/02/15 03:46

失礼しました。追記しました。 >該当のBlueprintのURLにアクセスした時で合ってますか。 その通りです。
guest

回答1

0

ベストアンサー

環境が作れないので、なにか情報が無いか調べて見ました。

以下に、pynamodbを使ったExampleがありました。

こちらが参考にならないでしょうか?

chaingng /shoeisha_serverless_python_tutorial

投稿2023/02/17 13:41

FiroProchainezo

総合スコア2401

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

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

MagMag

2023/02/18 00:21

ありがとうございます。元々そのアプリを写経して構築していったのですが、その本にはBlueprintの分割方法については載っていません。
FiroProchainezo

2023/02/20 01:47

だとすると、以下の質問の方ですかね https://teratail.com/questions/9p9nyqc2pv9sc5 ただ、こちらの回答だと最終的に諦めているので、微妙かもしれません。 いろいろなサイトを見ましたが、その部分の設定をapp経由のconfigから読んでいるサンプルが見当たりませんでした。 直接書いてしまうか(table_name='table'みたいな)、config.pyなどをimportして使った方が早いかもしれません。(from config import TABLE_NAME; table_name=TABLE_NAMEみたいな)
MagMag

2023/02/21 00:20

ありがとうございます。 with app.context()構文の中でimportすることで対処療法的にできたのですが、この方法だと、別のモジュールでこのclassを呼ぶ(たとえばDBを作成したり削除する)時も、いちいちapplicationを呼ばないとならず、気持ち悪い感じでした。 おっしゃるとおり、configをimportする形で検討しようと思います!
FiroProchainezo

2023/02/21 00:57

自分なりの解決策ができたら、自己解決の回答で質問を締めて下さい。 Flaskの拡張にDynamoDBを使う物があったので、そちらを使っても良いかもしれません。 この辺でしょうか https://pypi.org/project/dynamodb-session-flask/ 比較的更新が新しく、メジャーバージョンが1以上のものですが、0.0.2よりましなだけで微妙かもしれません。
MagMag

2023/02/28 06:25

ありがとうございます。current appを使わず、おっしゃるとおり、config.pyをimportする方法で実装しました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問