目次
models
リポジトリは複数のユーザーを持ち、ユーザーは複数のリポジトリを持つ 多対多
転送・起動・Nodeバージョン Git
git add -A git commit -m "repository user save" git push
% DEBUG=otera-note:* npm run devstart
$ forever start bin/www % rsync -r --delete --exclude-from='exclude-list.txt' ~/otera-note/ jq:/home/jq/tera-note/
はい、特定のディレクトリで特定のNode.jsバージョンを固定することが可能です。そのためには、nodenvやnvmといったバージョン管理ツールを使用します12。 以下に、nodenvを使用して特定のディレクトリでNode.jsのバージョンを固定する手順を示します2。 cd ~/tera-note # 固定したいディレクトリに移動します。 nodenv local 20.10.0 # ディレクトリ固有のNode.jsバージョンを設定します。 上記のコマンドを実行すると、~/tera-noteディレクトリでは常にNode.jsのバージョン20.10.0が使用されます2。 また、nvmを使用する場合は、.nvmrcというファイルを作成し、その中に使用したいNode.jsのバージョンを記述します3。以下にその手順を示します。 cd ~/tera-note # 固定したいディレクトリに移動します。 echo "20.10.0" > .nvmrc # .nvmrcファイルを作成し、使用したいバージョンを記述します。 上記のコマンドを実行すると、~/tera-noteディレクトリではnvm useまたはnvm installコマンドを実行するときに、自動的に.nvmrcに記述されたバージョンが使用されます3。
h1= title p Welcome to #{title}
てぷノートからデータベース移行
jq@ubuntu:~/tep5$ psql tep5_production -W -c "COPY (select * from fam_others_client_district_class_kai_addr2 where note_id = 1) TO STDOUT WITH CSV HEADER" > ~/csv-back/others_jq.csv Password:
CREATE TABLE familymembers AS SELECT clients.id, clients.note_id, lists.content AS lists_content, lists.list_line, clients.content AS clients_content, clients.client_line, clients.memo FROM clients JOIN lists ON clients.list_id = lists.id; CREATE TABLE familymembers2 AS SELECT f.client_id, f.note_id, f.lists_content, f.list_line, f.clients_content, f.client_line, f.memo, f.id, c.content AS categories_content, c.category_line FROM familymembers f JOIN relationship_categories rc ON f.client_id = rc.client_id JOIN categories c ON rc.category_id = c.id WHERE c.content IN ('檀家', '信徒', '離檀', '絶家', '不明', '一般', '寺院', '他檀家', '業者'); SELECT * FROM familymembers2 WHERE client_id IN ( SELECT client_id FROM familymembers2 GROUP BY client_id HAVING COUNT(*) > 1 ); CREATE TABLE familymembers3 AS SELECT f.*, p.zip, p.ken, p.city, p.etc, p.flag, p.memo AS places_memo FROM familymembers2 f LEFT JOIN places p ON f.client_id = p.client_id; —————————————————————————————————— CREATE TABLE places_flag_true AS SELECT id, note_id, client_id, zip, ken, city, etc, flag, memo FROM places WHERE client_id IN ( SELECT client_id FROM places GROUP BY client_id HAVING COUNT(*) > 1 ) AND flag = true; CREATE TABLE places_flag_false AS SELECT client_id, zip, ken, city, etc, flag, memo FROM places WHERE client_id IN ( SELECT client_id FROM places GROUP BY client_id HAVING COUNT(*) > 1 ) AND flag = false; DELETE FROM places_flag_false WHERE etc = ''; DELETE 28 tep5_production=# select count(*) from places_flag_false ; count ------- 93 CREATE TABLE places_multi_flag_false_no_multi AS SELECT client_id, zip, ken, city, etc, flag, memo FROM places_flag_false WHERE client_id IN ( SELECT client_id FROM places_flag_false GROUP BY client_id HAVING COUNT(*) = 1 ); SELECT 79 CREATE TEMPORARY TABLE places_1_2 AS SELECT p2.*, t.zip AS zip2, t.ken AS ken2, t.city AS city2, t.etc AS etc2, t.flag AS flag2, t.memo AS memo2 FROM places_flag_true p2 LEFT JOIN temp2 t ON p2.client_id = t.client_id; 重複を分ける CREATE TEMPORARY TABLE temp3 AS SELECT client_id, zip, ken, city, etc, flag, memo FROM temp WHERE client_id IN ( SELECT client_id FROM temp GROUP BY client_id HAVING COUNT(*) > 1 ); CREATE TEMPORARY TABLE temp4 AS SELECT * FROM temp3 ORDER BY client_id; -- 偶数IDのテーブルを作成 CREATE TABLE temp4_even AS SELECT * FROM pg_temp_3.temp4 WHERE id % 2 = 0; -- 奇数IDのテーブルを作成 CREATE TABLE temp4_odd AS SELECT * FROM pg_temp_3.temp4 WHERE id % 2 != 0; CREATE TABLE places_cp AS SELECT * FROM places; SELECT id, note_id, client_id, zip, ken, city, etc, flag, memo FROM places_cp WHERE client_id IN ( SELECT client_id FROM places_cp GROUP BY client_id HAVING COUNT(*) > 1 ) places_cpから重複した行を削除したい。 places_cpから SELECT client_id, array_agg(id) AS ids FROM places_cp GROUP BY client_id HAVING COUNT(*) > 1;の結果を削除したい。 places_multi_flag_false_no_multiテーブルにtemp4_even INSERT INTO places_multi_flag_false_no_multi (client_id, zip, ken, city, etc, flag, memo) SELECT client_id, zip, ken, city, etc, flag, memo FROM temp4_even; ———————————————————————————————— CREATE TABLE public.fam_others_client_district_class ( id bigint, note_id bigint, client_id bigint, client_name boolean, name character varying, kana character varying, other_line integer, memo_other text, generation character varying, lists_content character varying, list_line integer, client_line integer, categories_content character varying, category_line integer, memo_client text ); INSERT INTO public.fam_others_client_district_class SELECT o.id, o.note_id, o.client_id, o.client_name, o.name, o.kana, o.other_line, o.memo, o.generation, CASE WHEN o.client_name = true THEN f.lists_content ELSE NULL END, CASE WHEN o.client_name = true THEN f.list_line ELSE NULL END, CASE WHEN o.client_name = true THEN f.client_line ELSE NULL END, CASE WHEN o.client_name = true THEN f.categories_content ELSE NULL END, CASE WHEN o.client_name = true THEN f.category_line ELSE NULL END, CASE WHEN o.client_name = true THEN f.memo ELSE NULL END FROM public.others o LEFT JOIN public.fam_client_district_class f ON o.client_id = f.client_id; othersのすべての行を挿入したい。その中でclient_name = trueの行には f.lists_content, f.list_line, f.client_line, f.categories_content, f.category_line, f.memoを追加したい。 ——————————————————————————————————— Table "public.fam_others_client_district_class" Column | Type | Collation | Nullable | Default --------------------+-------------------+-----------+----------+--------- id | bigint | | | note_id | bigint | | | client_id | bigint | | | client_name | boolean | | | name | character varying | | | kana | character varying | | | other_line | integer | | | memo_other | text | | | generation | character varying | | | lists_content | character varying | | | list_line | integer | | | client_line | integer | | | categories_content | character varying | | | category_line | integer | | | memo_client | text | | | Table "public.kaimyous" Column | Type | Collation | Nullable | Default --------------+--------------------------------+-----------+----------+-------------------------------------- id | bigint | | not null | nextval('kaimyous_id_seq'::regclass) user_id | bigint | | not null | note_id | bigint | | not null | client_id | bigint | | not null | other_id | bigint | | not null | content | character varying | | | birth | date | | | death | date | | | g_age | character varying | | | relationship | character varying | | | memo | text | | | public.fam_others_client_district_classにpublic.kaimyousをLEFT JOINし、public.fam_others_client_district_classにcontent, birth, death, g_age, relationship, memo列を追加したい。 ALTER TABLE public.fam_others_client_district_class ADD COLUMN kaimyou character varying, ADD COLUMN birth date, ADD COLUMN death date, ADD COLUMN g_age character varying, ADD COLUMN relationship character varying, ADD COLUMN memo_kaimyous text; UPDATE public.fam_others_client_district_class f SET kaimyou = k.content, birth = k.birth, death = k.death, g_age = k.g_age, relationship = k.relationship, memo_kaimyous = k.memo FROM public.kaimyous k WHERE f.id = k.other_id; UPDATE 3838 tep5_production=# select count(*) from kaimyous; count ------- 3842 —————————————————————————————————— Table "public.fam_others_client_district_class" Column | Type | Collation | Nullable | Default --------------------+-------------------+-----------+----------+--------- id | bigint | | | note_id | bigint | | | client_id | bigint | | | client_name | boolean | | | name | character varying | | | kana | character varying | | | other_line | integer | | | memo_other | text | | | generation | character varying | | | lists_content | character varying | | | list_line | integer | | | client_line | integer | | | categories_content | character varying | | | category_line | integer | | | memo_client | text | | | kaimyou | character varying | | | birth | date | | | death | date | | | g_age | character varying | | | relationship | character varying | | | memo_kaimyous | text | | | tep5_production=# \d places_cp Table "places_c”p Column | Type | Collation | Nullable | Default -----------+-------------------+-----------+----------+--------- id | bigint | | | note_id | bigint | | | client_id | bigint | | | zip | character varying | | | ken | character varying | | | city | character varying | | | etc | character varying | | | flag | boolean | | | memo | text | | | zip2 | character varying | | | ken2 | character varying | | | city2 | character varying | | | etc2 | character varying | | | flag2 | boolean | | | memo2 | text | | | zip3 | character varying | | | ken3 | character varying | | | city3 | character varying | | | etc3 | character varying | | | flag3 | boolean | | | memo3 | text | | | public.fam_others_client_district_classにplaces_1_2_3をLEFT JOIN したい。 client_idが同じで、さらに、client_nameがtrueの場合は、 次の値を追加したい。 zip ken city etc flag memo zip2 ken2 city2 etc2 flag2 memo2 zip3 ken3 city3 etc3 flag3 memo3 public.fam_others_client_district_classのすべての行を結果に反映し、新しいテーブルをつくりたい。 CREATE TABLE fam_others_client_district_class_kai_addr2 AS SELECT f.*, COALESCE(p.zip, '') AS zip, COALESCE(p.ken, '') AS ken, COALESCE(p.city, '') AS city, COALESCE(p.etc, '') AS etc, COALESCE(p.flag, false) AS flag, COALESCE(p.memo, '') AS memo, COALESCE(p.zip2, '') AS zip2, COALESCE(p.ken2, '') AS ken2, COALESCE(p.city2, '') AS city2, COALESCE(p.etc2, '') AS etc2, COALESCE(p.flag2, false) AS flag2, COALESCE(p.memo2, '') AS memo2, COALESCE(p.zip3, '') AS zip3, COALESCE(p.ken3, '') AS ken3, COALESCE(p.city3, '') AS city3, COALESCE(p.etc3, '') AS etc3, COALESCE(p.flag3, false) AS flag3, COALESCE(p.memo3, '') AS memo3 FROM public.fam_others_client_district_class AS f LEFT JOIN places_cp AS p ON f.client_id = p.client_id AND f.client_name = true; SELECT 5558
設計
セッションを使用することにはメリットとデメリットがあります。以下にそのいくつかを挙げてみましょう。
- メリット:
1. **簡単な実装:**
- セッションは一般的に実装が簡単で、多くのウェブフレームワークやライブラリでサポートされています。特に小規模なアプリケーションにおいて、簡潔なコードでセッションを利用できます。
2. **セキュリティ:**
- セッションは一般的にサーバーサイドで管理されるため、クライアント側で変更されにくく、セキュリティが向上します。特にセッションIDを安全に扱えば、不正なアクセスを抑制できます。
3. **一時的なデータ保存:**
- ユーザーが一時的なデータを保持するのに適しています。たとえば、ログイン状態、ショッピングカートの内容など、セッションを使用することで簡単に管理できます。
- デメリット:
1. **サーバーの負荷:**
- 多くのセッション実装ではサーバーサイドでのデータ管理が必要です。セッションデータが増えるとサーバーの負荷が増加する可能性があります。
2. **スケーラビリティの制約:**
- セッションデータがサーバーサイドに保存されるため、複数のサーバーでアプリケーションをスケーリングする場合、セッションの同期が必要になります。これは管理が複雑になる可能性があります。
3. **データの保存場所:**
- セッションデータがサーバーサイドに保存されるため、データの永続性が低いことがあります。サーバー再起動やセッションの有効期限切れなどにより、データが失われる可能性があります。
4. **クライアント側のストレージ:**
- セッションIDをクライアントに保存するため、クッキーやLocalStorageを使用することがあります。これには一部のセキュリティ上の懸念が伴います。
セッションを利用するかどうかは、具体的なアプリケーションの要件と特性に依存します。セッションのメリットを最大限に引き出すためには、適切な実装とセキュリティ対策が必要です。
URL パラメータを使用することには、いくつかのメリットとデメリットがあります。
- メリット:
1. **簡易な実装:**
- URL パラメータはクエリ文字列として直接指定できるため、実装が比較的簡単です。特に小規模なアプリケーションや単発の操作に適しています。
2. **ブックマークや共有:**
- URL パラメータに情報が含まれるため、特定のページや状態に直接アクセスするためのブックマークやURLの共有が容易です。
3. **クライアントサイドでの変更が可能:**
- クライアントサイドの JavaScript から簡単に URL パラメータを変更できます。これは、ユーザーが操作する対話型のページにおいて便利です。
- デメリット:
1. **セキュリティ上の懸念:**
- URL パラメータにはセキュリティ上の懸念があります。特に機密情報やパスワードなど、公開されてはいけない情報を URL に含めるべきではありません。
2. **URL の複雑性:**
- 多くのパラメータが必要な場合や、パラメータの組み合わせが複雑になると、URL が長く複雑になる可能性があります。これは可読性やメンテナンス性に影響を与えることがあります。
3. **ブラウザの制限:**
- URL の最大長は制限されており、一部のブラウザでは制約があるかもしれません。長大な URL は正しく処理されない可能性があります。
4. **セッション管理が難しい:**
- セッション管理が必要な場合、セッション ID を URL パラメータに含めることはセキュリティ上の問題があるため推奨されません。
5. **履歴管理:**
- ページ遷移において、URL パラメータによる情報の履歴管理が難しい場合があります。
URL パラメータを利用するかどうかは、アプリケーションの要件やセキュリティ上の配慮によります。セキュリティが重要な場合や、複雑なデータ管理が必要な場合は、他の手段を検討する必要があります。
中間コレクションを使用することにはいくつかのメリットとデメリットがあります。
- メリット:
1. **柔軟性:**
- 中間コレクションを使用することで、関連性のある情報を構造的に管理できます。複数のコレクションを繋げることができ、データモデリングが柔軟になります。
2. **スキーマの変更が容易:**
- 関連する情報が変更された場合、それぞれのコレクションのスキーマを変更することができます。これにより、データの構造を簡単に変更できます。
3. **パフォーマンスの最適化:**
- 特定の情報にアクセスする際に、中間コレクションを使用することでパフォーマンスを最適化できる場合があります。特に大量のデータがある場合、中間コレクションによってクエリの効率が向上することがあります。
- デメリット:
1. **データ整合性の維持が難しい:**
- 中間コレクションを使用する場合、データの整合性を保つために追加の処理が必要です。トランザクションがサポートされていないデータベースでは、データ整合性の維持が難しくなることがあります。
2. **データベースの複雑性:**
- 中間コレクションを使用することで、データベース全体の構造が複雑になる可能性があります。これはメンテナンスや開発の際に混乱を招く可能性があります。
3. **パフォーマンスへの影響:**
- 中間コレクションを使用すると、データの検索や結合が複雑になり、パフォーマンスに影響を与えることがあります。特に適切なインデックスの設定が必要です。
4. **データの取得が複数回必要:**
- 関連する情報が別々のコレクションに格納されている場合、データを取得するために複数回のクエリが必要になることがあります。これは、データの一貫性を保つために追加の処理が必要な場合があります。
5. **データの冗長性:**
- 中間コレクションを使用すると、同じ情報が複数のコレクションに格納されることがあり、データの冗長性が生じる可能性があります。
中間コレクションを使用するかどうかは、アプリケーションの要件やデータベースの特性によります。データの関連性や取得パターンに応じて最適な方法を選択する必要があります。
準備
バージョン確認
% node --version v20.10.0 2023年12月20日現在、Node.jsの最新安定版はv20.10.0
% npm show express express@4.18.2 2023年12月20日現在、Expressの最新バージョンは4.18.1
% npm install express-generator -g
% mkdir tera-note % cd tera-note
% express --view=pug teranote % cd teranote
% npm install
% DEBUG=teranote:* npm start
Express で Tailwind を使うには、以下の手順を実行します。 1. npm で Tailwind をインストールします。 2. Tailwind の設定ファイルを作成します。 3. Express アプリで Tailwind を有効にします。 ### 1. npm で Tailwind をインストールする Tailwind をインストールするには、次のコマンドを実行します。 ``` npm install tailwindcss ``` このコマンドを実行すると、Tailwind がインストールされます。 ### 2. Tailwind の設定ファイルを作成する Tailwind の設定ファイルを作成するには、次のコマンドを実行します。 ``` npx tailwindcss init ``` このコマンドを実行すると、`tailwind.config.js` ファイルが作成されます。 `tailwind.config.js` ファイルで、Tailwind の設定を変更することができます。 ### 3. Express アプリで Tailwind を有効にする Express アプリで Tailwind を有効にするには、次の手順を実行します。 1. Express アプリの `index.js` ファイルで、`tailwindcss` を `dependencies` または `devDependencies` に追加します。 2. `index.js` ファイルで、`tailwindcss` を `import` します。 3. `index.js` ファイルで、`express.static()` を使用して、Tailwind の CSS ファイルを読み込みます。 たとえば、次のコードのように `index.js` ファイルを変更すると、Tailwind が有効になります。 ```javascript const express = require('express'); const path = require('path'); const app = express(); // Tailwind CSS を dependencies に追加 // または // Tailwind CSS を devDependencies に追加 app.use(express.static(path.join(__dirname, 'node_modules', 'tailwindcss', 'dist', 'tailwind.min.css'))); app.get('/', (req, res) => { res.send('Hello, world!'); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` このコードを実行すると、Tailwind を使用してレンダリングされた、次の HTML が生成されます。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello, world!</title> <link href="/tailwind.min.css" rel="stylesheet"> </head> <body> <div class="text-center"> <h1>Hello, world!</h1> </div> </body> </html> ``` ### その他のオプション Tailwind を Express で使用するときに、次のオプションを設定することもできます。 * `tailwind.config.js` ファイルで、`purge` オプションを指定すると、Tailwind で使用されていない CSS を削除できます。 * `tailwind.config.js` ファイルで、`content` オプションを指定すると、Tailwind で使用される CSS を変更できます。 * `index.js` ファイルで、`express.style()` を使用して、Tailwind の CSS を直接適用することもできます。