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

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

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

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

3回答

2217閲覧

開発環境ごとにconfigを読み替える

sequelanonymous

総合スコア123

Flask

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/10/09 08:59

編集2018/10/10 06:49

test.py/staging.py/production.pyのそれぞれ3つのconfigファイルがあります。
この三つの環境の違いは、year.pyはローカル環境、staging.pyはGAE環境、production.pyはGKE環境です。
下記のコードにどう追記していけば、これらのconfigの読み替えができるようしたいです。
現状、test.pyのconfigを読むように書いていますが、これを3つ増やすだけでは駄目だと思っています。
条件分岐か何かかくべきでしょうか? こうかけるというのがあれば、ご教示いただけませんでしょうか?

wsgi.py

python

1* create_appは、initファイルからimport 2import os 3from xxx import create_app 4 5if os.environ.get("DEBUG"): 6 logging.basicConfig(level=logging.DEBUG) 7 8if __name__ == '__main__': 9 app = create_app('test') 10 app.run(host='127.0.0.1', port=8080, debug=True)

追記

test.py(ローカルで動かす用のconfigファイル)

import os from pathlib import Path from module.config.base import Config basedir = Path(__file__).parent.parent.parent class LocalConfig(Config): TESTING = True DEBUG = True SQLALCHEMY_DATABASE_URI = "sqlite:////" + os.path.join(basedir, "test.db") @staticmethod def init_app(app): pass

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

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

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

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

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

mather

2018/10/09 09:12 編集

config.py ファイルを参照するようにしておいて、 configファイルそのものを置き換えることは出来ないのですか?
sequelanonymous

2018/10/09 10:32

すみません、イメージわかないのでもう少し具体的に教えて頂けませんでしょうか?
guest

回答3

0

ベストアンサー

以下のようにして環境に配置したときに staging.pyconfig.py にコピーすればいいのでは?

python

1import os 2from config import create_app, app_name 3 4debug = False 5 6if os.environ.get("DEBUG"): 7 logging.basicConfig(level=logging.DEBUG) 8 debug = True 9 10if __name__ == '__main__': 11 app = create_app(app_name()) 12 app.run(host='127.0.0.1', port=8080, debug=debug)

投稿2018/10/09 10:37

mather

総合スコア6753

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

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

mather

2018/10/09 10:38

app_nameを勝手に追加しましたが、引数が環境別で違うだけなら create_app() で十分なのでは。
sequelanonymous

2018/10/09 10:45

ありがとうございます。多分、誤解が生じている気がしているかもしれません。上記、私が記載したコードは、wsgi.pyに書いており、各環境ごとのconfigファイルは別にあり、creat_app()の引数にそのconfigファイル名を記載することで読み込むというようにしています。環境ごとにconfigファイルを読み込むようにしたいです。現状だと、test.pyというconfigファイルを読み込むには、creat_app('test')と指定する必要があります。if __name__ == '__main__':がtrueのときという条件つきで。これをcreat_app('staging')やcreat_app('production')というようにできればよいのかなと勝手なイメージを考えています。
mather

2018/10/09 10:47

from test import create_app ここで test.py を読み込んでいるんじゃないんですか?
mather

2018/10/09 10:52

実行後にimportするファイルを変更することはできません。できることと言えば別のPythonプロセスを呼び出して実行するか、execを使ってファイルの内容を評価するかですが、 execは危険なためあくまでも最終手段だと思ってくださいね。 設定ファイルという話で言うならPythonファイルである必要はないはずで、例えば configparser を使うべきかと思います。
sequelanonymous

2018/10/09 11:36

すみません、私の記載ミスでした。from test import create_appのtestは、creat_app('test')で指定しているtestとは異なります。モジュール名が入ります。転記する際に修正したところ、たまたま名前がかぶりました。
mather

2018/10/09 14:24

なんにせよ、すでに回答したとおり読み込むPythonファイルを切り替える手法は使うべきではないと思います。 configparserやその他設定ファイルで挙動を切り替えることを考えてみてください。
sequelanonymous

2018/10/09 14:57

ありがとうございます。言葉足らずで伝わらづらかったと思いますが、当質問の本質的な部分は、実行される環境ごとに読み込むconfigファイルを切り替えられるか?できるならばどうできるか?です。 やりたいことは、実行される環境ごとに読み込むconfigを変えたいです。つまり、おそらく__name__の値ごとに異なるかなと思っています。 test.pyはローカル環境、staging.pyは、docker上かつGAE、production.pyはdocker 上かつGKEです。
mather

2018/10/09 17:53

あなたが本質的と思っている以上は何も言いませんが、私からは憶測と思い込みが先行してしまって本当は何がしたいのか冷静に整理できていないように見えます。 __name__の値はモジュールとして読み込まれたときの完全修飾名です。 https://docs.python.jp/3/reference/import.html?highlight=name#__name__ 実行してみるとわかりますが、importしたファイルごとで__name__で参照される値は決まりますし、環境による違いはないはずです。 あなた自身が環境別の値を環境変数などで設定しない限り、環境の違いをアプリケーションが自動的に識別する方法はないと考えてください。
mather

2018/10/09 17:55

そもそも、test.pyの中身って何なのですか?参考までに質問に追記していただけると助かります。
sequelanonymous

2018/10/10 00:10

すみません、もしかしたら、私が何かしら誤解している可能性がある気もしてきました。その誤解もときたいという思いがあります。上記に test.pyの中身を追記しました。
mather

2018/10/10 02:07

うーん。何がしたいのかはやはり謎です。 > stating.py及び、 production.pyはそれぞれ、環境ごとの環境変数がかかれている。 とありますが、 TESTING = True DEBUG = True のような大文字表記の変数のことを「環境変数」と言っていますか?これは環境変数ではないです。 環境変数は実行しているOSが管理しているもので実行プロセスごとに設定されており、Pythonからは os.environ でアクセスします。 もしかしてこういうことがしたかったんでしょうか。 https://qiita.com/ukisoft/items/8912d0a66151609d9ff9
sequelanonymous

2018/10/10 06:50

はい、そのURLに記載しているようなことがやりたいことです。
sequelanonymous

2018/10/10 07:02 編集

そのURLに記載しているやり方だと、読み込む settings のconfigを手動でTerminalから打って変えているように見ますが、これ以外の方法はないものでしょうか?
mather

2018/10/10 07:24

手で打って変えているのは Heroku アプリケーションの設定値(環境変数)です。Herokuの場合は基本的にこの手段しかありません。 Herokuなどのサービス設計を理解する上で参考になる 12-Factor App という資料のURLを置いておきます。 https://12factor.net/ja/
sequelanonymous

2018/10/10 08:52 編集

herokuは使わないんですよね。ありがとうございます。dockerの場合は普通どうするものでしょうか?
mather

2018/10/11 01:16

Dockerを使う場合、test, staging, production でDockerイメージは共通にすべきだと思います。 docker run の -e オプションで環境変数が設定可能なので、そちらを利用するといいと思います。
sequelanonymous

2018/10/18 02:29

返事、遅くなり、すみません。ありがとうございます。腑に落ちました。
guest

0

test.py/staging.py/production.pyのそれぞれ3つのconfigファイルがあります。

各環境に、この3ファイルのいずれか1つがある、ということであれば、各々のファイルの存在チェックを行って環境の特定をしつつ、katsukoさんのコードの要領でimportするファイルを切替える方法が無くもないです。
(が、私であればその方法は採りません。matherさんの書かれている方法を採ります)

投稿2018/10/09 15:19

morinatsu

総合スコア395

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

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

0

create_appメソッドの中で、渡された名前をもとにtest.py/staging.py/production.pyのいずれかのモジュールをインポートして処理したいということでしょうか。

例えば、

python

1# coding: utf-8 2# test.py 3 4def call_my_name(): 5 print('test')

python

1# coding: utf-8 2# staging.py 3 4def call_my_name(): 5 print('staging')

python

1# coding: utf-8 2# production.py 3 4def call_my_name(): 5 print('production')

だとします。

方法1: モジュール名ではなく、モジュール自体を渡す

python

1def create_app(module): 2 module.call_my_name() 3 4if name == 'test': 5 import test as conf_module 6elif name == 'staging': 7 import staging as conf_module 8else: 9 import production as conf_module 10 11create_app(conf_module)

方法2: importlibを使う。

python

1import importlib 2 3def create_app(name): 4 m = importlib.import_module(name) 5 m.call_my_name() 6 7if name == 'test': 8 create_app('test') 9elif name == 'staging': 10 create_app('staging') 11else: 12 create_app('production')

3つしかないのであれば、前者の方法でいいと思います。

投稿2018/10/09 14:27

編集2018/10/09 14:30
katsuko

総合スコア3462

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

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

sequelanonymous

2018/10/09 14:52

ありがとうございます。私の言葉足らずで少し誤解招いているかもしれません。 create_appメソッドの中で、渡された名前をもとに ではありません。 また、create_app内で呼ばれ値によってでもありません。 実行される環境ごとに読み込むconfigを変えたいです。つまり、おそらく__name__の値ごとに異なるかなと思っています。 test.pyはローカル環境、staging.pyは、docker上かつGAE、production.pyはdocker 上かつGKEです。
katsuko

2018/10/10 00:10 編集

GAEもGKEも知りませんが、結局のところmatherさんのやり方で解決するのではないですか。 私もmatherさんの回答で解決しなさそうなので回答しましたが、コピー一回で解決するのであればこんな馬鹿らしいやり方はしません。(知識として知っておくといいと思って回答しましたが) そもそも、「__name__」が何なのか、理解していますか? (「おそらく」という話をすれば、私は関係ないと思います。あくまで「おそらく」ですが)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問