ギャバンITサービス
お菓子の家が作れるシステムエンジニアです

djangoをdockerコンテナで利用(15) - djangoでsql直接発行

djangoでレコードの集計してたら、どうしてもできない集計があることに気づいた。 仕方がないので、直接sql発行して集計させることにした。 sqlを文字列として準備し発行すると、仮にexceptionが発生したときにもそれをエラーログとして出力させるようにした。 ログ出力 はmariadbに出力するようにしてる。 今回はレコード集計結果を作ったのでそのメモ。 結論 djangoで経費のレコードを処理する画面を作ってる途中。 これから「編集」と「操作」の列にボタン足して編集・コピー・削除の機能をつけてこうとしてる。 他の画面で既に「編集」と「操作」は作ってあるから、djangoのviewsにはコピーして作れば余裕。 経費テーブルには、かかった費用の目安を記録しときたいから、自作の科目も含んでて、実際の「水道代」とか「外食費」もつけて台帳管理してる。 自宅で業務をしてると「水道光熱費」ってのは、実生活でかかる水道代や電気代を業務と生活で按分しなきゃいけないから、全部を計上しちゃいけない。 確定申告で使う経費科目は決まっているから、自作の経費科目は経費計上しないようにしたい。 けれど、djangoではその科目に応じた集計をさせられない場面があった。 予想してたけど、やっぱりできん集計あるんやなぁ。 (自分がまだ見つけられてないだけかもしれん) さっさと進めて作りたかったから、直接SQLの文字列を発行して集計結果を表示させるようにした。 djangoの基本機能で集計できなかったのは、経費合計。 理由は経費テーブルから外部参照する科目テーブルに、経費対象の列があって、外部参照する列をdjangoのfilterで指定できなかったから。 指定するとエラーになって、実テーブルに存在する項目しか指定を許可してくれなかったから。 その他の、医療費控除とか売上合計なんかの科目狙い打ち集計はできてた。 自分のテーブル設計がマズいのかもしれんけど、既存のphp版からの移行作成やから、保管構造は変えない方針。 (idの列は足したけど・・・) 処理優先で考えるんじゃなく、データベース優先で考えるから、djangoの機能を使えるところだけ使って、実際の集計はsql書くことにした。 既存のphp版にある過去7年分、84か月分の経費合計がきっちりあってた。1円も狂ってなくて気持ちよかったなぁ。 djangoは「SQL書かなくても動く」ってのがいいところ、みたいな書き方を見かけるけど、DBMSの集計機能を使ってSQLで書いたほうがいいこともあると思う。 実際の開発でSQL書けない人がたまにいるけど、RDBを扱うときにSQL書けなかったら、本番開始後のDB関連障害や高速化に対応できないんじゃないかとも思う。 例えばoracleからpostgresqlに移行するときのことを考えて、sqlは一切書かずに全部djangoに任せるっていうのはいいことかもしれんけど、そういう見込みがないんやったらベタのSQL書いて楽したほうがええんとちゃうか? サンプルデータ 例えばこんなデータがあったとする。 月間の売上とか経費が入ってる。 経費テーブル workPeriodは、経費計上の年月だけ使ってるから、全部1日の0:00:00って入ってる。 Kamokuは、科目テーブルにある科目番号と科目名が埋め込んである。 id workPeriod workShubetsu workPriority Keihi_date Kamoku Tehai Kng Biko 9058 2022/03/01/火 0:00:00 1yan 1001 2022/03/10/木 0:00:00 008-給料賃金 給与 60000 20140924申請の青色事業者専従者給与に関する届出書により10万円を目標に計上。 9059 2022/03/01/火 0:00:00 1yan 1002 2022/03/10/木 0:00:00 020-水道光熱費 光熱費 10000 50%を事業用の電気代とする。月平均2万円x50%=1万円。 9068 2022/03/01/火 0:00:00 1yan 1003 2022/03/10/木 0:00:00 025-通信費 インターネット/電話利用料 10000 電話とインターネットは50%を事業用の電気代とする。月平均2万円x50%=1万円。 9060 2022/03/01/火 0:00:00 2kgc 1010 2022/03/31/木 0:00:00 101-現金売上 amazon販売 0 物販(3/xx) 9077 2022/03/01/火 0:00:00 2kgc 1020 2022/03/10/木 0:00:00 102-預金売上 お客様 100000 xxx案件 9074 2022/03/01/火 0:00:00 2kgc 1047 2022/03/31/木 0:00:00 023-損害保険料 xx保険 6550 エージェント会社提供の掛け捨て保険 9087 2022/03/01/火 0:00:00 2kgc 1068 2022/03/05/土 0:00:00 003-研究開発費 定食屋 1630 IT市場調査。昼食。 9070 2022/03/01/火 0:00:00 2kgc 1072 2022/03/06/日 0:00:00 001-打合会議費 喫茶xx 2480 月初打合せ 9101 2022/03/01/火 0:00:00 2kgc 2019 2022/03/20/日 0:00:00 003-研究開発費 apple 4787 mp4解析用 9055 2022/03/01/火 0:00:00 3ikk 1042 2022/03/31/木 0:00:00 038-外食費 外食費累積 1467 目安 9056 2022/03/01/火 0:00:00 3ikk 1043 2022/03/31/木 0:00:00 039-食費 食費累積 74120 目安 9051 2022/03/01/火 0:00:00 3ikk 1045 2022/03/31/木 0:00:00 099-預金残高 銀行残高 0 残高確定 9085 2022/03/01/火 0:00:00 3ikk 1046 2022/03/31/木 0:00:00 040-水道代 大阪市水道局 3842 1月分水道代。1月13日検針。22立米。(クレカ引き落とし) 9054 2022/03/01/火 0:00:00 3ikk 1053 2022/03/31/木 0:00:00 041-電気代 関西電力 19738 3月分電気代。919kwh。 経費種別テーブル workShubetsuは経費の種別で、djangoのtemplatesで表示させるときの色指定が一緒に入ってる。 ...

 ⭐️

djangoをdockerコンテナで利用(14) - djangoでblobカラムを含むレコードのコピー

djangoでblob列を含むレコードを作成・更新・参照・削除することができるようになった。 自分特有の blob操作 もできるようになった。 ただ、これだけでは自分にとって使える処理とは言えない。 普段は一度入力した内容をコピーして再作成することのほうが多い。 1から入力するんじゃなく、既存レコードをコピーして更新しながら作る。 そのほうが楽やし。 今回はレコードをコピーする処理を作ったのでそのメモ。 結論 実際の作りはこうなった。 月間作業予定の一覧を年月単位で存在させてて、優先順位を番号として付けてある。 listviewを使って一覧表示させたレコードに「行コピー」ってボタンを作って、そのレコードをコピーし、ボタンを押すとそれ以降のレコードの優先順位を+1する。 例えばこういうレコードがあって3列目にあるコピーボタンを押すと、 こうなる。 4列目に優先順位「27」ってあるレコードがコピーされて「28」ができてる。 ここで「27」からさらにコピーすると、「27」と「28」は「28」と「29」になって、元の27を新規レコードとして保管する。 右端の3列にガッキーのjpeg、五線譜のpdfの1ページ目をjpeg変換したもの、ガッキーの別のjpegがちゃんと入ってコピーされている。 しっかしガッキーかわいい。 格納したファイルと性能 jpegは100KB程度やけど、pdfはムーンライトソナタの譜面で16ページ、7.5MB程度ある。 それをbase64でエンコードして保管するから、容量は1.5倍程度として1レコードはたぶん10MB強。 それでもdjango的には1秒もかからず処理してくれている。 20件ある先頭レコードでコピーしても同じやった。 数百件とか数千件だと時間かかるのかもしれないけど、ここではこれで十分。 dockerコンテナでもこれぐらい動いてくれるんやなぁ。 レコードの構成 jpegとpdfは実表示用データ(longblob)だけでなく、一覧表示するときのための縮小版(mediumblob)を持ってる。1レコードに3つの添付ができるように、同じようなフィールドが3つずつある。 mariaDB上の定義 前回のblob操作は在庫のテーブル使ってたけど、今回は活動テーブル。 BLOBって名前で始まる列の定義は他のテーブルも完全に同じ。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 CREATE TABLE `GVIS_work` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', `workPeriod` datetime DEFAULT NULL COMMENT '業務期間-開始日', `workShubetsu` char(4) DEFAULT NULL COMMENT '作業種別', `workPriority` int(10) DEFAULT NULL COMMENT '優先順位', `Category1` varchar(100) DEFAULT NULL COMMENT 'カテゴリ1', `Category2` varchar(100) DEFAULT NULL COMMENT 'カテゴリ2', `Tehai` varchar(10000) DEFAULT NULL COMMENT '手配方法・名称・機種', `Kazu` decimal(12,4) DEFAULT 0.0000 COMMENT '数量', `Tnk` decimal(12,4) DEFAULT 0.0000 COMMENT '単価', `Kng` decimal(12,4) DEFAULT 0.0000 COMMENT '金額', `WorkTime` decimal(12,4) DEFAULT NULL COMMENT '作業時間', `Biko` varchar(100) DEFAULT NULL COMMENT '備考', `BLOB_data1` longblob DEFAULT NULL COMMENT 'BLOBデータ1', `BLOB_data2` longblob DEFAULT NULL COMMENT 'BLOBデータ2', `BLOB_data3` longblob DEFAULT NULL COMMENT 'BLOBデータ3', `BLOB_extent1` varchar(100) DEFAULT NULL COMMENT '添付mime1', `BLOB_extent2` varchar(100) DEFAULT NULL COMMENT '添付mime2', `BLOB_extent3` varchar(100) DEFAULT NULL COMMENT '添付mime3', `BLOB_medium1` mediumblob DEFAULT NULL COMMENT '添付-埋め込み画像用1', `BLOB_medium2` mediumblob DEFAULT NULL COMMENT '添付-埋め込み画像用2', `BLOB_medium3` mediumblob DEFAULT NULL COMMENT '添付-埋め込み画像用3', `ins_date` datetime DEFAULT NULL COMMENT 'データ作成日', `ins_user` varchar(100) DEFAULT NULL COMMENT 'データ作成ユーザ', `upd_date` datetime DEFAULT NULL COMMENT 'データ更新日', `upd_user` varchar(100) DEFAULT NULL COMMENT 'データ更新ユーザ', PRIMARY KEY (`id`), KEY `IDX_work` (`workPeriod`,`workShubetsu`,`workPriority`,`Category1`,`Category2`,`Tehai`(255)) ) ENGINE=InnoDB AUTO_INCREMENT=1502 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC django内のmodels.pyの定義 blob列はdjangoではTextFieldになる。 ...

 ⭐️

djangoをdockerコンテナで利用(13) - Google Cloudとローカルlinuxの環境切り替えスクリプト

djangoで作っている処理をローカルlinuxで開発し、Google Cloudの中に反映させる。 前回 にGoogle Cloudの本番環境を作った。 作り終わった直後、できてない件があるなって気づいた。 ローカル開発環境はcssで画面を緑色系にしてるのを、本番は青色にしたい DBは開発用のDBインスタンスを使ってるので切り替えたい ヘッダの中に「ログアウト」のリンクがあるのが使えない これはGoogle Cloudとローカルlinuxでそれぞれtemplatesに置くhtmlやsettings.pyを用意しておき、コンテナを起動するときに切り替えればいい。 そこで、dockerのコンテナをdocker-composeで起動するとき、その直前にファイルコピーするようにスクリプトを書き換えた。 結果 ローカルlinuxでこう見えてるのが、 こうなる。 想定しているファイルを用意して上書きコピーしたら、すんなりできた。 データベースも複数あるのを切り替えて使えるようになった。 開発環境では好き放題データベース書き換えてテストできるのは必須やし。 以下、変更実施スクリプト作成内容。 前提 ローカルlinuxもGoogle Cloudも、docker-compose.ymlを複数使ってる。 webアプリ、mariadb、gitlab、ubuntu20のrdp環境を起動して帳簿入力 oracle起動してちょっとSQL試したいとか、検証するための環境を起動 centos7、centos8、ubuntu20など複数のOSフレーバーへsshできるようにし、OS利用してdockerfile作るための環境を起動 それぞれ永続化領域を持たせていて、「今日はcentosの検証作業」とか「今日は帳簿入力」とか使い分けてる。 dockerだと、サーバの役割をホイホイ変えられるから、必要なサービスを必要なだけ起動すればいい。 コンテナ起動のための基礎になるスクリプトはこう書いている。 1 2 3 4 5 6 7 8 DOCKER_ROOT=/Docker cd ${DOCKER_ROOT} ### cp -p docker-compose-GVISweb.yml docker-compose.yml ### cp -p docker-compose-DBMS.yml docker-compose.yml ### cp -p docker-compose-Client.yml docker-compose.yml docker-compose up -d cpしている箇所のうち、どれか1つだけコメント箇所を外して使ってる。 ...

 ⭐️

djangoをdockerコンテナで利用(12) - Google Cloudに実行環境作成

資産や取引の登録・更新画面がdjangoでできつつある。 ようやっとphpから脱却できるメドがついた。 あとは作っていくだけ。 ローカルでの開発環境は使えているので、次は本番環境を用意する。 開発してテスト終わったら、git管理のソースをgoogle cloudの中のサーバで動かせるようにする。 コンテナ作って永続化領域に作ったソースを置き、sslのコンテナ経由で公開させてブラウザで使う。 今回はその環境作成メモ。 ローカルlinuxはubuntu20が動いていて、google cloudからコピーしたphp/mariadbのコンテナが動いている。他にも練習用のコンテナが一時的に動いてる。 google cloudにはローカルlinuxと同じubuntu20が動いていて、その中にphp/mariadb/gitlab/rdpのコンテナが動いている。 ここにdjangoとsslのコンテナを追加して、rdpのコンテナからssl経由でdjangoのコンテナをブラウザ経由で使う。 djangoのソースはgit管理していて、ローカルlinuxで開発した結果をgoogle cloud内に持って行って永続化領域にコピーして使う。 できた結果をgoogle cloudのrdpコンテナに接続して使ったらこんな感じ。 どっかで悩むかと思ったら、スンナリできた。 docker様ありがたや、ありがたや。 準備 djangoの管理テーブルを丸ごと開発環境からコピーし、djangoとssl公開用のコンテナを作って、google cloud内のrdp環境にあるブラウザで表示できるようにする。 ホンマにちゃんと動き続けられるのか心配やけど、やりながら考えていく。 データベースの準備 データベースはmariadb利用。 開発用DBはnariDB_Djangoって名前。nariDB_1stっていう本番データベースのコピーも含んでローカルlinuxのnafslinux.intra.gavann-it.comで持たせてる。 一番上にあるgcp-gvis-docker-mariadbがgoogle cloudにある本番データベースで、nariDB_1stって名前で持たせているので、ここにdjango用の管理テーブルを作る。 いきなり作って失敗したらツラいので、ローカルlinuxにある同じnariDB_1stで練習してからgoogle cloudの本番データベースに対して実施する。 この作業では、作業で失敗しないようにコピー元のデータベースは読み込み専用で開くこと、コピー先のデータベースはmysqldumpで事前にバックアップを取ってあることに必ず留意した。 djangoが管理している対象テーブルの特定 自分の業務テーブルは13個。 GVISで始まる名前のテーブルで、資産管理とか取引とかがblobまじりのテーブルに入ってる。 djangoはmigrateとかして自動生成され、専用のテーブルを10個使ってる。 auth_xxxとdjango_xxxって名前のがそれ。 ホンマa5sqlあると助かる。作者さんありがとう。 対象テーブルのcreate 定義はローカル開発環境のものを10個そのままa5sqlで参照してそのまま使う。 よく見ると外部キーみたいなのがついてる。 たとえばauth_permissionのテーブルにcontent_type_idって列があって、FOREIGN KEYの箇所からdjango_content_typeってテーブルのidって列を参照してる。 1 2 3 4 5 6 7 8 9 10 CREATE TABLE `auth_permission` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `content_type_id` int(11) NOT NULL, `codename` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `auth_permission_content_type_id_codename_01ab375a_uniq` (`content_type_id`,`codename`), CONSTRAINT `auth_permission_content_type_id_2f476e4b_fk_django_co` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=141 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ; こういうときは、FOREIGN KEYの記述で参照される側から順番にcreate tableしてデータを入れて行かないと、うまくレコードが入っていかない。 ...

djangoをdockerコンテナで利用(11) - vscodeでソース編集

vscodeを使っていると、左端に拡張機能があってgit操作とかマークダウンのプレビューとか気軽に使える。 しかもwindows/mac/linuxでほぼ同じような操作と利用感が得られる。 さすがms。 めっちゃ便利。 visual basic2.0で初めてソース書いた時に同じような感動があったな。 djangoって拡張機能を入れておくとシンタックスを補正してくれたり、作ったviews/models/formsなんかを入力候補に表示してくれて、選ぶと勝手にコードを補ってくれる。 書き方の記憶が曖昧だったり、こう書けば処理として行けるかなって思ったとき、試し入力するとその候補を見せてくれるのはとても助かる。 ついでにgit関連の拡張機能も入れておくと、コミットとプッシュをいちいちコマンドラインで入力しなくていい。 何か問題出た時だけ手入力でgit操作することもあるけど、あまりに楽すぎて手入力のやり方忘れた。手でやるのはgit cloneぐらいか。 自分のdjango環境はlinuxサーバにあるdockerコンテナをsslコンテナを通して表示させている。 今回はこのコンテナで使うdjangoソースをmacで編集するときのメモ。 環境 googleクラウドを本番環境に見立てて使ってる。 4コア16GBメモリにhdd300GB。ssdはそれほど性能出ないのに単価高いからhddでいい。 容量は多いほどいいけど300GBで足りるし、消費量じゃなくて確保量で課金やから、300GBならだいたい1200円ぐらい。そこにcpuやらメモリ使用が足されてく。 xrdpコンテナはubuntu20のXwindowが使える。 2年ぐらい前までcentos7のxrdpコンテナを作って使ってたけど、centos8になったらめっちゃ不安定になったので、dockerhubでたまたま見つけたubuntuのxrdpに変えた。 ローカルPCから rdp接続 して、ブラウザでphpアプリケーション使ってる。 gitlabの管理はxrdpコンテナに入れたvscodeとブラウザでやってる。 xrdpの中で全部済ませることで、下りパケット料金も抑えられる。 アプリケーションはgit cloneしてzipしておき、データベースはエクスポートした結果をzipで固めて、google driveにバックアップ入れておく。 ローカルlinuxへは、cyberduckとか使ってこのバックアップを取りに行き、展開用のバッチ処理をスクリプト化して作っておいて同じものを展開する。 google cloudへローカルの内容を反映させるときも同じ感じで使う。 googleクラウドの中は異様にネットが速くて、1500Mbpsぐらい速度が出るから、合計10GBぐらいのzipでも10分もあればバックアップ終わる。 7割がhddの費用で、週1回ぐらい使って、google cloud月額2000円未満。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 +------------------------------+ |google | | +--------------------------+ | | | ubuntu20 | | | | +---------------------+ | | | | | docker | | | | | | +----------------+ | | | | | | | mariadb | | | | | | | +----------------+ | | | | | | | | | | | | +----------------+ | | | | | | | php | | | | | | | +----------------+ | | | | | | | | | | | | +----------------+ | | | | | | | gitlab | | | |⭐️ここでソース管理 | | | +----------------+ | | | | | | | | | | | | +----------------+ | | | | | | | xrdp | | | |⭐️ここでlinuxのgui使えるのでvscodeやブラウザ使う | | | +----------------+ | | | | | +---------------------+ | | | +--------------------------+ | +------------------------------+ ローカルlinuxサーバはgoogleクラウドのコピーみたいなもので、djangoへのリプレース開発を今はやってる。 ...

 ⭐️