[PHP/Laravel] Eloquentモデルで初期値(デフォルト値)を設定したいときは$attributesを触ってなんとかする。

どうもこんにちは。

今回言いたいことは、すでにタイトルで9割ぐらい説明し終わってしまっているのですが、一応そこに思い至った経緯と詳細を書き連ねておこうと思います。

データモデルのデフォルト値を予め決めておきたい場合、Migrationのロジックの中でdefault()を使えば設定できますが、これはデータソースに対する操作なので、あまり適切ではないと考えました。(データソースが変わればそんなメソッドは簡単に使えなくなってしまうため。)

デフォルト値は業務ルールに関わる事が多いので、なるべくドメインモデルに当たる箇所に入れるべきだと思いました。
そこで、デフォルト値を入れたいEloquentモデルのコード内に、以下のように記述しました。

これで、新規にモデルを生成したときに、対象プロパティにデフォルト値が挿入されます。

この辺の説明、Laravelのリファレンスには無かったとです(´;ω;`)

以下の記事を参考にしました。
How to set a default attribute value for a Laravel / Eloquent model?

[Python3] 相対パスのimportで上位ディレクトリを指定できない問題とその対策いろいろ

Pythonで自作モジュールをインポートするときに、相対パスで指定する方法があります。
Pythonをそこそこ覚えてきたら、1枚ファイルにベタ書きなんてやってらんないので、当然いくつかのファイル(モジュール)に割りますよね。
そんなことをしていると、上位ディレクトリにあるモジュールを使いたくなることがめっっっっっっちゃ出てくるので、実行スクリプト内で、

のように書いたんですけど、どうもこの書き方、使えないみたいです……

Pythonでは、モジュールをimportする際にsys.pathに入っているパスのリストを見ているみたいなのですが、どうもこれらのパスから上位ディレクトリに遡るような動きができないみたいです。
じゃあなんでこんな書き方サポートしたんや(´・ω・`)

参考→6. モジュール (module) — Python 3.6.5 ドキュメント
https://docs.python.jp/3/tutorial/modules.html#the-module-search-path

Python実行時に、ファイルが有るディレクトリのパスを自動的にsys.pathに挿入してくれるので、同階層のモジュールは触れるみたいです。
でも上層にあるモジュールを使いたみMAXなので、どうにかして使えるようにしてみた解決策をメモしておきます。

解決策1:sys.pathに直接パスを入れる。

sys.pathの実態はリストなので、スクリプト内でいくらでも触りたい放題です。
そこで、import前にモジュールのあるパスを直接ぶっこみます。

__file__の親ディレクトリをappendしています。parentを2回続けているのは、1回だとファイル名を取り除くだけになってしまい、ファイルのあるディレクトリになってしまうからです。

でも、スクリプト内で直接sys.pathをいじるのはどうなんでしょう?

解決策2:一番上の階層に実行ファイルを持ってくる。

上に遡れないならば、すべてを見渡せる位置に持ってくれば問題ありません。
シンプルな解決策でいい感じですが、これだと一つの階層にたくさんのファイルがあふれることにもなりかねません。それでも良いぐらい小さなプロジェクトなら問題ないですが、それならそもそもモジュール分けする必要もないかも……

解決策3:実行時、PYTHONPATHにパスを挿入する。

多分このやり方が一番いい感じなのではないでしょうか??

リファレンスにも書いてありましたが、実行時にはPYTHONPATHの値もsys.pathに含めてくれるみたいです。
そこで、pythonコマンドを実行する前にPYTHONPATHの値を書き換えれば、スクリプトを汚さずにsys.pathをコントロールできます。

この手の実行環境構成の変更は、VSCodeだと簡単にできますね。
プロジェクト内の.vscode/launch.jsonで、使用中のビルド構成に環境変数を書き加えます。

まとめ

Pythonよくわからん
VSCodeまじ神
https://code.visualstudio.com/

[Python3]タスクスケジューラー経由で動作させると、コンソールが消えない問題をどうにかしたい。

最近、ふと思い立ってPythonを始めました。

といっても近頃流行りの機械学習的なものではなく、Seleniumを使ったブラウザの自動操作をやりたくて覚えたんですけどね(´・ω・`)

さてタイトルの話題。
(自分の環境はWindows10上でAnaconda5.2.0を使って開発しております。その前提でお聞きください。)

作ったコードをタスクスケジューラーを使って動作させると、なぜかコンソールが動作終了後も出っぱなしになってしまいます。
1日になんども動かすので、あまり出っぱなしにはなってほしくない!何とかしたい!……と思って調べていたら、2つほど手段が出てきました。

①pythonw.exeを使う。

pythonにはランタイムが2つあるらしくて、コンソールを出す「python」の他に、コンソールを表示しない「pythonw」なるものがあるみたいですね……
これならはじめからコンソールが出ないので、問題にならないです。
python使いの方なら「何アタリマエのこと言うてんねん!」て感じでしょうが、まじなんも知らんところからのスタートなんでゆるして(´;ω;`)

②システムコールを叩いてコンソールそのものを消す。

言われてみれば「なるほど」なんですけどね。

でもこれだと、同時に起動している他のタスクも消えてしまうかもしれないので、確実に1つしか消えない、というとき以外は微妙です。

 

まーおとなしくpythonwで動かすことにします。

参考サイト

windows – Python Scheduled Task Close taskeng.exe – Stack Overflow
https://stackoverflow.com/questions/28302795/python-scheduled-task-close-taskeng-exe

複数のfilebeatからlogstashへデータを流し込もうとしたらlogstashが死んだ

俺も死んだ(チーン

今頃なのか今更なのか知りませんが、Elasticstackに手を出し始めました。
柔軟性が高いのはいいけど、その柔らかさに殺されそうでまぢつらたんです(´;ω;`)

ちなみに構成は、
CentOS6
elastic 6.x
です。

さて、今回問題のケースでは、ログをfilebeatで取得して、logstashに流し込み、elasticsearchに書き込む構成を取りました。
そして、複数サーバーのログを集約させたいので、各サーバーにfilebeatを設置する、という形にしました。
図(?)にするとこんな感じ?ずれてたらごめんなさい
[FB]―[LS]―[ES]
[FB]/

これで動かしたけれども、elasticsearchのほうにIndexがさっぱり作られません。おかしいと思って/var/log/logstash/logstash-plain.logを見ると、以下のエラーがいっぱい書かれてました。

長すぎ!
まぁ要点は「Error: Cannot assign requested address」だと思います。

この時、2つのfilebeatが設定していたlogstashの宛先ポートはどちらも5044でした。
冷静になって考えたら、1つのポートを奪い合う状態はまずいので、片方のfilebeatのポートを5055に変更してやり直してみたら、普通に動きました!(∩´∀`)∩ワーイ

単純にポートの競合はやめましょうって話でした。よくよく考えると恥ずかしいw

[PHP] WindowsでCodeceptionを使うと、ChromeDriverが動かない!?

なんとか動くようになったけど、久々にめっちゃハマった(´;ω;`)

 

最近のChromeって、コード経由でコントロールするときにSeleniumを挟まずにChromeDriver単体で触ることができるんですね。知らずに生きてましたわ;;

というわけで、CodeceptionでChromeDriver経由でChromeを触ってみました。

(ちなみに、使用しているOSはWindow 10 Home 64bitで、Git Bash(64bit)をインストールして、これをシェルとして使っています。)

この辺のChromeDriverを使うまでの手順は公式ページのWebDriverのページに書いてあるものをそのまま実行しています。

To run tests in Chrome browser you may connect to ChromeDriver directly, without using Selenium Server.

1. Install ChromeDriver.
2. Launch ChromeDriver: chromedriver --url-base=/wd/hub
3. Configure this module to use ChromeDriver port:

引用元: WebDriver – Codeception – Documentation (http://codeception.com/docs/modules/WebDriver#ChromeDriver)

 

この通りにやってみて、シェルで「./vendor/bin/codecept run」と走らせてみたのですが、エラーが発生します。

「レスポンスがJSONデコードできないよ!」って言うエラーですけど、問題はそこではなくて、ChromeDriverからのレスポンスが「unhandled request」ってなってるところ。
一応Chromedriverをブラウザ経由で(http://localhost:9515)見てみましたが、同じレスポンスが帰ってきます。これじゃあさっぱり前に進みませんねぇ。

なぜなのかわからず、ChromeDriver周りのエラーをググっていったら、こんな記事を発見。

Issue with using selenium and webdriver doc · Issue #2968 · electron/electron · GitHub
https://github.com/electron/electron/issues/2968

Windowsでは動かないと、似たような問題を訴えてらっしゃいます。
そしてこの人がやってみたことは、–url-baseのパスを「wd/hub」にすること。

改めてコマンドを叩いたら、バッチリ動きました。

おうふ、マジかよ……(‘A`)

多分Linuxでは問題なく動くんだろうなぁ。
Windowsなんぞで動かすやつなんぞしらん!ってことなのでしょか?つらみ(´;ω;`)