【Python】【Flask-Migration】 flask db init でKeyError: 'migrate'って表示された。
こんばんは、葛の葉です。
flask-migrationを使っていて、コマンドでflask db init
と実行したらKeyError: 'migrate'
と表示されて実行されないということがありました。
File "/usr/local/lib/python3.6/site-packages/flask_migrate/__init__.py", line 125, in init directory = current_app.extensions['migrate'].directory KeyError: 'migrate'
環境
Python 3.6.6
Flask 1.0.2
Flask-Migrate 2.3.2
flask db initをする前に
flaskの起動方法について、認識をちょっと改める必要があって、そもそもflaskを起動するには以下のようにするのがお約束のようです。
flask run
python [flaskが記述されたpythonファイル]
では正しい方法では無いようです。
それで、flaskは環境変数FLASK_APP
に入っているpyファイルを読み込む設定のようで、環境変数FLASK_APP
に中身が存在しない場合は、app.py
を読み込むようになっているようです。hello.py
にflaskのコードがある場合は以下のようにします。
export FLASK_APP=hello.py flask run
flask-migrate
のコマンドflask init db
とする場合もFLASK_APP
が該当のものでないと駄目のようです。
stackoverflowで見てみる
from flask_migrate import Migrate migrate = Migrate(app, db)
こうしなさいと書いてあった。
結局こうなった
# app.py from flask_migrate import Migrate from factory import create_app from objects.database import db app = create_app() migrate = Migrate(app, db) if __name__ == '__main__': app.run()
app.py
がおいてる場所をカレントディレクトリにして、flask db init
が動いた。
上記のインポート先のコード
# factory.py from flask import Flask from objects.database import db def create_app(): app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'hogehoge' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True db.init_app(app) return app
# objects/database.py from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() def init_db(app): db.init_app(app)
【Oracle VirtualBox】ブリッジ設定を使ってホストマシンのローカルネットワークからゲストマシンにアクセスする
こんにちは、葛の葉です。
ホストマシンのローカルネットワーク環境からゲストマシンにアクセスする方法を記載します。
環境
Oracle VirtualBox 5.2.22 Host Windows 10 Home Guset Ubuntu 16.04
ブリッジ設定をする
VirtualBoxの画面でアクセスしたいゲストマシンを選択した状態で設定ボタンを押下します。左タブのネットワーク
を選択し、アダプター1の割り当て
のプルダウンメニューをブリッジアダプター
にして、名前
のプルダウンメニューを現在のローカルネットワークに接続している"ホストマシンのネットワークアダプタ"にします。
次にゲストマシンを起動してShellで以下のコマンドを打ちましょう。
ip address
また、ip a
でもいいです。自動補完してa
がaddress
に変換されるっぽいので。(Aliasかも?)
そうすると、どこかのインターフェースでホストマシンと同じネットワークに繋がっているアドレス
が存在しているのでメモってください。(この辺ざっくりしててごめんなさい🙇)これがこのゲストマシンにアクセスするためのIPアドレスになります。
アクセスしてみる
例えばそのゲストマシンにNginxを導入していたら、192.168.1.?1にブラウザでアクセスするとWelcome to nginx!
がちゃんと表示されているはず。
同じネットワーク内ならスマホからでもアクセス可能です。
【Python】Flaskでcreate_app関数を作って使う
こんばんは、葛の葉です。
今回はFlaskで調べものをしているとよく見かけるcreate_app
関数を使ってみます。
環境
Python 3.6.6
Flask 1.0.2
ディレクトリ構成はこちら
カレントディレクトリ ├── app_factroy.py ├── app.py └── test_app.py
create_appを作る
# app_factroy.py from flask import Flask def create_app(config_mode='test'): app = Flask(__name__) if config_mode == 'test': app.config['DEBUG'] = True app.config['SQL_ADDRESS'] = '127.0.0.1' else: app.config['DEBUG'] = False app.config['SQL_ADDRESS'] = '69.196.1.1' return app
create_app
関数はFlask(__name__)
のインスタンスであるapp
に様々なコンフィグを与え、最終的にそのapp
を返却します。create_app
関数の引数config_mode
には開発環境か、テスト環境か、本番環境か、といった環境のステータスを渡してあげます。
create_appを呼び出す
# app.py from app_factroy import create_app app = create_app('dev') # import os # app = create_app(os.getenv('FLASK_CONFIGURE_MODE')) # 以下何らかの処理 if __name__ == __main__: app.run()
create_app
関数を呼び出して、引数に環境情報を与えます。返り値をapp
変数に代入します。そうしてapp.run()
してあげれば、Flaskは実行されます。
また、os.getenv
を使って環境変数から環境情報を与えるのもありかなぁと思います。今回のコメントアウト部分がそれです。FLASK_CONFIGURE_MODE
という環境変数内にtest
とか入れておくと、create_appの引数にtest
が入ります。いいねぇ。
下記の記事を参考にベストプラクティスなコンフを作ると良いのでは、と思います。というか、私はそうやってます。ありがとうございます。
create_appでtestする
# test_app.py from app_factroy import create_app app = create_app('test') assert '127.0.0.1' == app.config['SQL_ADDRESS']
こんな感じで呼び出してテストしてあげましょう。実行したら何も起こらずにコマンドラインが返ってくると思います。(なんかあったらテスト落ちてるって意味です。)
【Python】配列コピーについて
こんばんは、葛の葉です。
さて、Pythonの配列のコピーについて、書きます。
環境
Python3.6.6
コード達
Python 3.6.6 (default, Sep 5 2018, 03:40:52) [GCC 6.3.0 20170516] on linux Type "help", "copyright", "credits" or "license" for more information. >>> a = [1,2,3,4,5] >>> b = a >>> a [1, 2, 3, 4, 5] >>> b [1, 2, 3, 4, 5]
>>> a[0] = 6 >>> a [6, 2, 3, 4, 5] >>> b [6, 2, 3, 4, 5] #←b[0]が変更されている
>>> id(a) 140405585847624 >>> id(b) 140405585847624 >>> id(a) == id(b) True #IDの値は全く同じである。
配列の中身をコピーしているわけではなく、配列として参照しているアドレスをコピーしているため。
配列をコピーしたい場合
import copy
を用いたコピー
c
配列
>>> import copy >>> c = copy.deepcopy(a) >>> id(c) 140405578255624 >>> id(a) == id(c) False #<- IDが異なる >>> c [6, 2, 3, 4, 5]
>>> c[0] = 7 >>> c [7, 2, 3, 4, 5] >>> a [6, 2, 3, 4, 5]
>>> a [6, 2, 3, 4, 5] >>> b [6, 2, 3, 4, 5] >>> c [7, 2, 3, 4, 5] >>> a[0] = 8 >>> a [8, 2, 3, 4, 5] >>> b [8, 2, 3, 4, 5] >>> c [7, 2, 3, 4, 5]
スライス[:]
を用いたコピー
d
配列
>>> d = a[:] >>> d [8, 2, 3, 4, 5] >>> d[0] = 9 >>> d [9, 2, 3, 4, 5] >>> a [8, 2, 3, 4, 5]
>>> id(d) 140405578255688 >>> id(d) == id(a) False >>> id(d) == id(a) False
結論
リストをコピーするときは
import copy new_array = copy.deepcopy(array)
または
new_array = array[:]
【Discord】Botから役職へのメンション方法
こんばんは、葛の葉です。
ちょっと前に会社でDiscord使ってる旨お伝えしたかと存じますけど、そんな中でDiscord内の役割(権限)にメンションを飛ばしたくなりました。それが意外と日本語に乗っていなかったのでこちらに記載します。
役職にメンション飛ばすんだって
実は以下に記載の通り。でも、最初見たときよくわからなかったのでざっくりと説明すると役割に一回特殊なメンション飛ばすと、その飛ばしたときの書き込みがちょっと変わった文字<@&????????????>
みたいなものになるので、Botを使うときはその<@&????????????>
を使うようにします。
やってみた
まず役割の設定をします。サーバー
を右クリックしてサーバー設定→役割をクリック。
飛ばしたい役職を選択してこの役職に対して@メンションを許可する
をオンにして保存
どこでもいいので\@<役職名>
と送信する。今回は\@ハンプティダンプティ
そうすると送信された文字がちょっと変わった物になっている。
<@$????????????????>
みたいなものが出ていると思うので、これをそのまま書き込めばその役職へのメンションになる。
botなんかに
botなんかで役職に送信したい場合は<@$????????????????>
を文字列に付け加えてあげればOKなはず。
【GAS】Googleフォームで入力してもらった値をLogger.logに出力する
こんばんは、葛の葉です。
さて、Googleフォームという大変便利がいいWebアプリがありますね。
これとGASを連携し、GAS上のLogger.logに出力することが出来ます。
こんなGoogleフォームです
問い合わせ内容
の中身をGASで取得するようにします。
スクリプトエディタを開く
先ずはスクリプトエディタを開きます。開き方はGoogleフォームのエディタモード
から右上のその他のボタン(黒点が縦に三つ並んでいるボタン)をクリックして、出てきたリストからスクリプト エディタ
をクリックしてください。
そうしたらスクリプトエディタ画面に移行するはずです。下記のようなコードが記載されていると思います。
function myFunction() { }
コードの記入
以下のように記入し、保存してください。(Ctrl + s)など。
function myFunction(event){ var values = event.response.getItemResponses(); var value = values[0].getResponse(); Logger.log(value) }
初めて保存する際はプロジェクトの名前を問われますので、お好みで。
トリガーの設定
スクリプトエディタ画面で「現在のプロジェクトのトリガー」ボタン(時計の形をしたボタン)があります。
それをクリックしてください。そうしますと、G Suite Developper Hub
というページに飛びます。右下の「トリガーを追加」ボタンをクリックします。
実行する関数を選択
がmyFunction
になっていることを確認した後、下部にスクロールした後イベントの種類を選択
をフォーム送信時
に変更してください。
保存をすればGoogleアカウントのことを聞かれますので、そこの対応をお願いします。
問題なければここで製作は完了しています。
実際にフォームに入れてみる。
こんな内容のものを送信します。
スクリプトエディタに移動して表示
-> ログ
としてみてください。
このようにログに出力されています。
Loggerlogの部分を変えてみましょう
例えば以前作成したDiscordに送信するための関数に渡してもよいでしょう。その他のチャットツールとかでも使えるんじゃないかなぁって思います。
【Python】受け取った配列に対し、Keyが1,2,3,4と連番した数字になるような辞書を返す関数 + Unittest
こんばんは、葛の葉です。
引数に配列を渡すと、連番をKeyにした辞書型を返してくれる関数を作りました。必要かどうかわかんないけど、一時、入用だったのですが、多分もういらない関数なのでここで供養させてください。
こんなんなのよ
関数numbering_dictionary()
の引数に['nezumi', 'ushi', 'tora', 'usagi']
のような配列を渡すと{1: 'nezumi', 2: 'ushi', 3: 'tora', 4: 'usagi'}
という辞書を返します。だからなんだってレベルのものですな。
関数はこんな感じ
helper_def.py
という名前で以下のコードを保存してください。
def numbering_dictionary(arry_choices_answer, start_key=1): ''' 受け取った配列に対し、Keyが1,2,3,4と連番した数字になるような辞書を返します。 ex: numbering_dictionary(['nezumi','ushi','tora']) -> {1: 'nemuzi', 2: 'ushi', 3: 'tora'} start_key(int)は連番開始の数字になります。デフォルトは1。 ''' numbring_dictionary = {} for index_number, choices_answer in enumerate(arry_choices_answer, start=start_key): numbring_dictionary[index_number] = choices_answer return numbring_dictionary
Unittestはこんな感じ
Unittest用プログラミングは以下になります。test_helper_def.py
みたいな名前でhelper_def.py
と同じところに保存してください。なお、動作させるだけならこのファイルは要らないです。
import pytest from . import helper_def def test_numbering_dictionary(): array1 = ['nezumi', 'ushi', 'tora', 'usagi'] array2 = ['serval', 'araisan', 'vulpes_zerda', 'silverfox'] array3 = ['one', 'two', 'three', 'four'] assert {1: 'nezumi', 2: 'ushi', 3: 'tora', 4: 'usagi'} == helper_def.numbering_dictionary(array1) assert {1: 'serval', 2: 'araisan', 3: 'vulpes_zerda', 4: 'silverfox'} == helper_def.numbering_dictionary(array2) assert {2: 'one', 3: 'two', 4: 'three', 5: 'four'} == helper_def.numbering_dictionary(array3, start_key=2)