OmniAICreator/Qiita-1.07M huggingface dataset:
RDBで後になって困ったこと３選

# その①安直フィールド追加
```php:UserModel
$table = ['id','name', 'email', 'phone'];
```
例えばusersとかいうテーブルがあるとして、アカウントの基本情報を含めておくときにフィールドとして持たせるのか、user_profileのような子テーブルを作成しそちらにプロフィールや連絡先などの情報を持たせるのか迷う時がある。安直に考えれば、フィールドでいいじゃんとなるが、これに苦しめられた。

##苦しむ原因①:フィールドが増えすぎる
後になってこれも必要これも必要という形で追加していくと、どんどんテーブルが肥大化し管理しにくくなる、挙げ句の果てにはジェイウォークとかJsonフィールドとかが出てくるともう触る気が失せる。

##苦しむ原因②:単一から複数への仕様変更
もともと、一つの情報しか格納しない予定だったのに、複数情報を格納するように仕様が変更される場合。既存のフィールドの利用をやめ、子テーブルを作成して管理するようになるが、なら元からテーブルを分けておくべき。

##苦しむ原因③：使用状況の管理
仕様の変更などで、あるフィールドをもう使わないなどになった時に、フィールドを簡単にドロップさせるのはあまりにもリスキー、IDE等の機能やテストで、落としても大丈夫そうなのは確認できるものの予期せぬ不具合が起こりかねず、起きた時フィールドが落とされていると復旧がめんどくさくなるので使用しなくなったとしても、ある程度の期間フィールドを残したまま様子を見たくなってしまう。（個人の感想）こうなると何時このレコード落としていいのか、誰が落とすのか、どうやって落とすのか、そのフィールドを使わない間どのように対応するのかなど管理するタスクがどっと増えしんどい。


#アンチ安直フィールド追加方針
 * 絶対に後になってフィールドが増えない事が保証されている場合にのみフィールドとする
 *  管理する情報が単一から複数に絶対に変更されない事が保証されている場合にのみフィールドとする
 *  該当テーブルにあるフィールドの属性（近しさ）が一致しない場合にはテーブルを極力分けるようにする

上2つは多分基本的なことなのだと思うが、3つめは個人的に思うとこと。卑近な例で言えば従業員テーブルに氏名、メールアドレスなどがあるとして、そこに緊急連絡先も管理するとなった時にフィールド追加せず、テーブルを分ける。従業員に関する情報だけれども属性的には従業員自身が所有するとは言い切れず、緊急連絡先も追加されるとなれば、住所や最寄駅、などなど他の情報を管理する必要も出てくるかもしれないため。これだけわかりやすければいいけど結構微妙なラインに遭遇したため今は迷ったら子テーブル。

#その②AUTO INCREMENT PRIMARY KEY
このマスターテーブル作り替える事ないでしょうと思っていたため任意のIDではなく、auto incrementのプライマリキーを使っていたら非常に管理しにくくなってしまった。

##苦しむ原因①:繊細な更新
既存のものを更新して、同時に新しいレコードを追加する必要が出たときは最悪。複数のテキストフィールドにwhereで検索をかけて、ある場合にはアプデ、ない場合には作成をしたが、そもそもある程度の長さのあるテキストで検索かける事自体に抵抗があるし、まかり間違って変更対象ではないレコードによきせぬ変更が加えられたら目も当てあられない。
10件とかの本当に極小のカテゴリー用のマスターテーブルとかであれば目視でまあなんとかすることもできるが、CSVから作成するマスターテーブルとなるとかなり精神を削られる更新作業になる。

##苦しむ原因②：IDの付け替え
やっぱり後から任意IDで管理したいとなると、当然これまでのプライマリキーから新しく作成したプライマリキーへの移行が必要になる。数多の関連テーブルの内容を一切のミスなく付け替える作業は当然精神が削られる。

#アンチAUTO INCREMENT　PRIMARY KEY方針
 * マスターテーブルはAUTO INCREMENTであるべき積極的理由がある場合以外には任意IDで管理する

#その③INDEXレス　スロークエリ
これは比較的軽めだけれど、えこの程度の件数でも必要だったの？！と思うことがあったので事前に知って起きたかった。というか検証しておくべきだった。

勝手に自分の中で100万とかのレコードから検索するならインデックスとかをよく考えて設計する必要があるんだろうなと思っていたら、7万件くらいですでにかなり遅かった。(７万件のレコードのupsertで３０分とか)

#アンチINDEXレス　スロークエリ方針
 * ダミーデータで実行速度を比較しIndexを貼る必要がありそうであれば貼る

#まとめ
数ヶ月スパンで過去の自分に首を絞められている気がしている。
レベル感的には、そこでつまづくとかwwwといったレベル感かもしれないけれど、自分への戒めと備忘録として記録。今まさに未来の自分か保守する他人の首を絞めようとしている人への気づきになれば幸い。

皆さんの経験した地獄があれば教えていただけると嬉しいです。
VScodeでESlintが適用されない

りあクト!第３版【II.React基礎編】をやっています。
6-1.ESlintでsrc/App.tsxを開いたけど、あんまりエラーが発生していない。
何か設定を間違えたかなと思いました。

VScodeの右下に「🚫ESlint」とあったので、そこをクリックして、「✔︎ESlint」としたらESlintが有効になって、エラーが複数あらわれました！
Windows10へのMYSQL(Zip版)インストール

#アーカイブ入手先

https://dev.mysql.com/downloads/mysql/5.7.html
から。ここでは5.7.32の例で。

#インストール
zip解凍して任意の場所に配置。スペースが入ったフォルダでもいいみたいだが、２バイト文字は不可。
ここでは「C:\mysql-5.7.32-winx64」に配置したとして。
配置先直下にmy.iniでファイル新規作成。中身は以下。

```[my.ini]
[mysqld]
character-set-server=utf8mb4
collation_server=utf8mb4_general_ci
init-connect='SET NAMES utf8mb4'
skip-character-set-client-handshake
port=3307
character-set-server=utf8mb4
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

[mysqldump]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

[client]
default-character-set=utf8mb4
```
コマンドプロンプトを管理者で起動。DB初期化を行う。rootの初期パスワードはログに吐かれるらしいが、Windowsだとどこにログがあるか不明だったので、初期パスワードなしでインストールしその後にパスワードを設定する方法をとった。
配置先直下にdataの名前でフォルダを作る。

```
> C:\mysql-5.7.32-winx64\bin\mysqld --defaults-file=C:\mysql-5.7.32-winx64\my.ini --initialize-insecure
```
何も出ずにかえってくれば成功。dataフォルダに何かあるとエラーになるのでその場合は空にして再実行。

サービスに登録する。

```
> C:\mysql-5.7.32-winx64\bin\mysqld --install MYSQL5_7_32 --defaults-file=C:\mysql-5.7.32-winx64\my.ini
Service successfully installed.
```

これでサービスダイアログからでも上げ下げできる。
rootのパスワードを設定する。

```
> C:\mysql-5.7.32-winx64\bin\mysql -u root -P 3307
mysql> alter user root@localhost identified by 'root';
Query OK, 0 rows affected (0.00 sec)
```

これでrootにもパスワードが設定できた。
あとはA5Mk2などのツールで。
Rails 日付カラムのバリデーション設定

#はじめに
Railsを使ってオリジナルアプリを開発しています。日付カラムに今日の日付より後(明日以降)は保存できないように、バリデーションを設定しました。忘れないように書き記します。


#目次
1.日付カラムのバリデーション
2.モデルへの追加記述

#1.日付カラムのバリデーション
今回suggestionテーブルにlast_cleaned_dateカラム(最後に掃除した日付)を作成した。下記のように空の場合、保存できないバリデーションは設定した。しかし、他カラムと異なり、空以外のバリデーションは別で行う必要がある。

```ruby:app/models/suggestion
class Suggestion < ApplicationRecord
  with_options presence: true do
#----------------中略-------------------    
    validates :last_cleaned_date #←対象のカラム
  end
  belongs_to :user
end
```

#2.モデルへの追加記述
同ファイルにバリデーションを追記する。ここではlast_cleaned_dateカラムが空でなかった場合、day_after_todayの処理が行われる。errors.addでエラーの種類を追加する。ここでもif文で条件を定義した。last_cleaned_dateが今日の日付(Date.today)より大きい場合、明日以降を示す。そして条件を満たした場合、保存されずエラーを表示する。

```ruby:app/models/suggestion.rb
validate :day_after_today
  def day_after_today
    unless last_cleaned_date == nil
      errors.add(:last_cleaned_date, 'は、今日を含む過去の日付を入力して下さい') if last_cleaned_date > Date.today
    end
  end
```
参考までに実装後のエラー表示画面を下記に示す。本日の日付(2020/11/19)で保存しようとした場合の、エラー文である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703987/1aa24f0d-2319-1f39-9304-98e916cecb73.png)


以上
BitbucketのPull Requestを効率化する3つの機能


https://bitbucket.org/user-name/repo-name/admin の「PULL REQUESTS」から設定できる3つの機能を紹介します。

## デフォルトのレビュアー

プルリクエスト作成時にデフォルトで補完されるレビュアーを指定できます。

## Default description

プルリクエストのテンプレートをMarkdownで設定できます。

## Excluded files

自動生成ファイルなど、プルリクエスト上で差分を非表示にしたいファイルを除外指定できます。
.gitignoreのフォーマットと同じなので、ワイルドカードなども使用できます。pattenは[こちら](https://support.atlassian.com/bitbucket-cloud/docs/exclude-files-from-pull-request-diffs/#Excludefilesfrompullrequestdiffs-Excludedfilespatternformat)
可変変数と可変関数 （PHP）

## 可変変数
変数を要いて、変数を動的に変える。

```php
class ClassName
{
    private $hoge = 'ほげ';
    private $fuga = 'ふが';

    public function say(string $name = 'hoge')
    {
        echo "{$this->$name}です。よろしく。";
    }
}

$class = new ClassName;
$class->say('hoge'); // ほげです。よろしく。
$class->say('fuga'); // ふがです。よろしく。
```

## 可変関数
動的に呼び出す関数（メソッド）を変える。

```php
class ClassName
{

    private $hoge = 'ほげ';
    private $fuga = 'ふが';

    public function say(string $name = 'hoge')
    {
        $method = "say$name";
        $this->$method();
    }

    private function sayHoge()
    {
        echo "{$this->hoge}だよ。みんな一度は聞いたことあるよね！！";
    }

    private function sayFuga()
    {
        echo "{$this->fuga}です。まだ聞いたことがない人もいると思うので、よろしくお願いします。";
    }
}

$class = new ClassName;
$class->say('hoge'); // ほげだよ。みんな一度は聞いたことあるよね！！
$class->say('fuga'); // ふがです。まだ聞いたことがない人もいると思うので、よろしくお願いします。
```
heroku run rails db:migrateできなかった時の話

herokuでデプロイしようとした際、データベースにマイグレーションの情報を入力

```
% heroku run rails db:migrate
```
入力、、、なんか違和感を感じる

logを遡っていくと

```
Mysql2::Error: Table 'heroku_XXXXXXXXXXXXXXXX.users' doesn't exist

　〜省略〜
```
とエラーが出てる

heroku上のuserテーブルが存在していないってこと？

当然、urlを指定しても画面には

![スクリーンショット 2020-11-19 21.51.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702376/8494cec1-ad5e-c7ab-5273-4150d6465e2a.png)

と表示される。

データベースのステータス確認

```
% heroku run rails db:migrate:status　
```
↓

```
Status   Migration ID    Migration Name
--------------------------------------------------
   (2.2ms)  SELECT `schema_migrations`.`version` FROM `schema_migrations` ORDER BY `schema_migrations`.`version` ASC
  down    202010XXXXXXXX  Create posts
  down    202010XXXXXXXX  Create active storage tablesactive storage
  down    202010XXXXXXXX  Devise create users
  down    202010XXXXXXXX  Create comments
  down    202011XXXXXXXX  Add columns to users
```

全ファイルupされてない。。。

## 試したこと


ローカルリポジトリでは問題なく反映されていたものの、一度こちらをリセットしてみようと試みる。

```
% rails db:migrate:reset
```

すると

```
Mysql2::Error: Table 'power_spot_development.users' doesn't exist

　　〜省略〜
```
えー
ローカルでもエラー発生

herokuでの状況と全く一緒で全ファイルがdown

マイグレイトできない


## 解決策
```
rails db:migrate:up VERSION=Migration ID
```
で一つづつファイルupしてみた。
すると

```
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20201021042500  Create posts
   up     20201023030611  Create active storage tablesactive storage
   up     20201023054938  Devise create users
   up     20201030032407  Create comments
   up     20201101015416  Add columns to users
```
全部マイグレーションできた！

herokuの方でも同じ動作を行う

```
heroku run rails db:migrate:up VERSION=Migration ID
```
全部upになった。

挙動も正常を確認

## 疑問点
なぜ、一つづつならマイグレートできたのか分からない
【Rails】ルーティングの確認（２パターン）

#ターミナルでルートを確認する
ターミナルに　$ rails routes　とコマンドを打つとルーティングが表示される

```terminal:ターミナル
$ rails routes

Prefix Verb   URI Pattern       Controller#Action
         new_user_session GET    /users/sign_in(.:format)        devise/sessions#new
             user_session POST   /users/sign_in(.:format)        devise/sessions#create
     destroy_user_session DELETE /users/sign_out(.:format)       devise/sessions#destroy
        new_user_password GET    /users/password/new(.:format)   devise/passwords#new
       edit_user_password GET    /users/password/edit(.:format)  devise/passwords#edit
            user_password PATCH  /users/password(.:format)       devise/passwords#update
                          PUT    /users/password(.:format)       devise/passwords#update
                          POST   /users/password(.:format)       devise/passwords#create
 cancel_user_registration GET    /users/cancel(.:format)         devise/registrations#cancel
```    
「ターミナルだと見にくいなぁ」と思ったことはないでしょうか！
そんな方には別の方法で確認することができます！
#ブラウザでルートを確認する

URLに http://localhost:3000/rails/info/routes にアクセス！
<img width="400" alt="スクリーンショット 2020-11-18 23.58.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863944/c272f672-a891-7996-9636-ee3bf9d273b4.png">

するとブラウザにルーティングが表示される！
<img width="1000" alt="スクリーンショット 2020-11-19 22.27.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863944/8a63b0c8-72c1-4456-18e4-192e1a5f076b.png">

ルートが増えるとターミナルでは確認し辛くなってくるのでコチラの方法はかなりオススメです！
ぜひお試しください！
0から始めるSwift実践入門の攻略作戦

オンラインスクールをやってみたけど、
やはり最初の基礎の基礎、ガチの座学は絶対必要と感じ、
参考書を買ってきて、まず基礎固めをしています。

# Swift実践入門の参考書で基礎を固める
![51sJhb6c0EL._SX352_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737820/c675de14-4287-5ee2-e599-8cd4f2c2548a.jpeg)
私の持っているこの参考書は、
__「2020年4月28日　第３版　第1刷発行」__のもの。

Sossiさんの記事を参考に、
この参考書をどう攻略するか、をまとめます。
[【Swift】未経験から実務までのスキルマップ(ロードマップ)](https://qiita.com/Sossiii/items/e2c846d12f2f5db7c426)

##【結論】まず最初に攻略すべき章
・第2章：変数と定数と式
・第3章：基本的な型
・第5章：制御構文
・第6章：関数とクロージャ
・第7章：型の構成要素
・第8章：型の種類
・第12章：型の設計指針
・第14章：非同期処理

##この参考書で、攻略できるレベル1の内容

__第2章__
・変数 var
・定数 let
・インスタンスとは
・プロパティとは

__第3章__
3.3-演算(+, -, *, /, %)、・比較演算子(==, !=)
3.8-型キャスト

__第5章__
5.2-if文、switch文
5.3-for文

__第6章__
関数 func (p128)

__第7章__
7.5メソッドとは

__第8章__
構造体：struct (p152,p189)

__*みつからなかった__
エスケープ処理「\()」

##この参考書で、攻略できるレベル2の内容
__第2章__
2.2-型推論

__第12章__
12.3-オプショナルがわかる

__第5章__
5.2-if let

__第3章__
3.5-オプショナルチェーン(p59)

##まずはこの参考書で、0から1へレベルアップをする
まったくの未経験、開発の経験もなし。
まったくの0からSwiftと戯れる人になる物語の、
__Episode1：基礎固め__　です。

仕事の日は、2〜3時間。
休みの日は、5〜6時間。
週20時間を目標に進めて行きます。
まず、この参考書を10日で一旦卒業することを目標に進めます。
【備忘録】VSCodeアップデートしたらprettier効かなくなった

#タイトルの通り
VSCodeアップデートしたらprettier効かなくなりました。
一度初めにVSCodeをインストールした時に効かなくて、困っていて教えていただいた方法を忘れて2時間かけて記憶を振り絞って思い出しました。

##試したこと
 
[prettierの使い方](https://qiita.com/kiida/items/405bb07c4b52bfee0219 
'prettierの使い方')
[VSCodeのprettierが効かないとき](https://qiita.com/Tmisatoy/items/0d4fcb2161e284817419
'VSCodeのprettierが効かないとき')
[formatOnSave がある日突然動かなくなった。Prettier VSCode](https://qiita.com/take_o/items/16beaec4619301ca8257
'formatOnSave がある日突然動かなくなった。Prettier VSCode')

##解決策
※VSCodeの右下の部分にPrettierと表示されていない人のみが解決対象になります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633274/57995c05-e09b-d48b-f97f-42c6d8f2b81d.png)

一番下のブランチ名をダブルクリックして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633274/e1d9dff2-5754-249c-8586-2e9db94dd0c6.png)

prettierクリックして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633274/75724c27-8f11-8d28-2b68-84feeb5cceb4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633274/979e210b-d2bd-17fd-d8d2-6542b06ca308.png)

効くようにになりました、、、、
VSCode初心者の方の参考になればいいです。
AWS〜EC2にRailsアプリのデータベースを作成・セットアップする〜

# この記事を読んでできるようになること
EC2にSSHログインし、**Railsアプリのデータベースを作成・セットアップする**ことができる。

今回は、**MariaDBをインストール**していきます（**Amazon Linux 2には、デフォルトでMariaDBがインストール**されているため）。ローカル環境のデータベースがMySQLの場合でも、問題なく動作します。
また、AWS上にデータベースを設置する方法は、EC2に設置する方法と、RDSを利用する方法がありますが、この記事では、前者の**EC2にデータベースを設置**する手順となります。
# 記事を読むにあたってのお願い
私は**AWSの初学者**で、アウトプットをすることで知識を定着させるためにこの記事を書いています。内容に誤りがある場合は、コメントをいただけますと幸いです。
# MariaDBとは
**MySQLから派生したRDBMS**(リレーショナルデータベースマネジメントシステム）です。**MySQLと高い互換性**があり、MySQLと比べて、**パフォーマンスや堅牢性が高い**という特徴があります。
# データベースの作成手順
**※[Railsの環境構築](https://qiita.com/kawano30/items/3dcda292419c0ccc8089)まで完了している前提です。**
**※MACでの操作手順となります。ご了承ください。**

## ① sshログインする

```
# pemファイルのあるディレクトリへ移動
  % cd 〇〇〇〇

# 秘密鍵（pemファイル）を使用して、EC2インスタンスにSSHログイン
  % ssh -i 〇〇.pem ec2-user@Elastic IP
```
## ② MariaDBをインストールする

```
# yumコマンドでインストール（yum: Linuxシステムにおけるソフトウェアパッケージの管理システム）
  ~ % sudo yum -y install mysql56-server mysql56-devel mysql56 mariadb-server mysql-devel
```
## ③ MariaDBの起動と起動確認する

```
# MariaDBの起動
  ~ % sudo systemctl start mariadb

# MariaDBの起動確認
  ~ % sudo systemctl status mariadb

# 以下のように、Active:が「active (running)」になっていればOK
  ● mariadb.service - MariaDB database server
   Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled)
   Active: active (running) 
```
## ④ データベースのrootユーザーのパスワードを設定する
※ 本番環境の**データベースのセキュリティを高める**ため

```
# 以下コマンドを入力
  ~ % sudo /usr/bin/mysql_secure_installation

# 現在のrootのパスワードを入力する（ない場合はEnterを押す）を言われるので、「Enter」を押す
  Enter current password for root (enter for none): Enter

# rootパスワードを設定するか聞かれるので、「Y」を入力
  Set root password? [Y/n] Y

# 新しいパスワードの入力を求められるので、自分が覚えやすいパスワードを入力しEnter
  New password: ********

# 再度入力を求められるので、もう一度パスワードを入力しEnter
  Re-enter new password: ********

# 「Success」と表示されれば設定完了
  ... Success!

# その後、何点か問われるので、全て Y を入力する。
  [Y/n] Y 
```
## ⑤ データベースにrootユーザーで接続する

```
# 以下コマンドを入力（rootユーザーで接続、-pはパスワードオプション）
  ~ % mysql -u root -p

# パスワードの入力を求められるので、先ほど設定したパスワードを入力後、Enter
  Enter password: ********

# MariaDBへようこそと表示されれば接続成功
  Welcome to the MariaDB ... （省略）

# 「exit」で接続解除
  > exit
```
これで、**データベースの設置**まで完了しました。

次回は**手動でデプロイ**を行っていこうと思います。
laravelで画像を再度指定せずに編集可能な機能を作成

初投稿です。これからプログラミング学習のアウトプット始めていこうと思います。

世の中のサイト（主にSNS）ってユーザーアカウントにアイコン（画像）が設定可能ですよね。
それを編集するときアイコン以外（名前、プロフィール等）だけ編集してアイコンはいじらない場合、アイコン画像はそのまま変更なしでプロフィールの変更ができます。
でも自分でlaravelでサイトを作ってみて気づいたのが画像に対してはoldヘルパーが適用されずどうやったらその機能を実現できるのかという点です。

今回自分なりに思いついた実装方法を紹介していきます。



#ルーティング

```php:web.php
Route::get('/posts/edit/{post}', 'PostsController@edit');
```

暗黙の結合を使って編集ページにpostsテーブルからカラムを持っていきます
今回画像のカラム名はpathになります。

#if文を使って実装できた

```php:PostsController@edit
 public function update(Request $request, Post $post) {
        // 画像変更の確認
        if(!empty($request->path)) {
            $file = $request->file('path');
            $filename = $file->getClientOriginalName();
            $request->file('path')->storeAs('public',$filename);
            $post->path = '/storage/' . $filename;
        }else {
            $post->path = $post->path;
        }

```

編集ページのsubmitボタンが押されたとき、$request->pathがあれば(新たに画像が挿入されているなら)新たに画像に対してユニークな名前をつけそれを投稿の画像としてデータベースに登録、そうでないならば(画像が変更されていないなら)以前の画像のパスを再代入してデータベースに登録

これで実装ができました！普段使い慣れているサービスの機能を実装できると気持ちがいいですね:relaxed:
[OCI]WebコンソールからDBCSのデータベース(18c)をOracle19cにアップグレードしてみた。

OCI WebコンソールからDBCSのデータベースのアップグレードが可能になったということで試してみた。

#前提条件
ベアメタルまたは仮想マシンのDBシステムでデータベースをアップグレードする前提条件は以下のとおり

- DBシステムはOracle Linux 7（OL7）を使用
- DBシステムのGrid Infrastructureは、Oracle Database 19cを使用
- データベースはアーカイブログモード
- データベースでフラッシュバックが有効
    - その後のUpdateでフラッシュバックが有効でない環境でも利用可能に。（切り戻し用スタンドアローンバックアップを取得を推奨）

#データベースのアップグレードについての注意点
- データベースのアップグレードには、データベースのダウンタイムが伴う
- Data Guardを使用している場合は、アップグレードする前にData Guardの関連付けを無効にするか削除する
- 本番データベースをアップグレードする前に以下を推奨
    - データベースのバックアップ取得する
    - テストシステムで新しいソフトウェアバージョンをテスト
- アップグレードを実行する前に、データベースのアップグレード事前チェック操作の実行を推奨
- 自動バックアップ操作の実行中は、アップグレード操作ができない
    - アップグレードする前に、自動バックアップを無効にして手動バックアップを実行することを推奨
- アップグレード後は、アップグレード前に取得したバックアップを使用して以前の時点にリカバリできない
- Oracle Database 11.2のデータベースをアップグレードする場合、バージョン19cデータベースは非コンテナーデータベースになる

#アップグレードが完了した後について

- Oracle DatabaseCOMPATIBLEパラメータを編集して、新しいOracle Databaseソフトウェアのバージョンを反映
- Databaseホストのoracleユーザの環境変数を新しいのOracle Databaseソフトウェアのバージョンを反映させる
- dbcli ultilityを使用して、古いOracle DatabaseHomeを削除することを推奨
- 必要に応じてデータベースの自動バックアップが有効になっていることを確認

#コンソールを使用したアップグレードと更新履歴の確認
##コンソールを使用したアップグレード
1. Webコンソールから > [データベース] > [ベアメタル、VM、およびExadata] をクリック
2. コンパートメントを選択
3. DBシステムのリストからアップグレードするシステムの詳細を表示
4. データベースのリストからアップグレードするデータベースの名前をクリックして詳細表示
5. リソースから[更新]をクリック
    - 「Oracle提供のデータベース・ソフトウェア・イメージ」タブには、データベースをより高いメジャーリリースバージョンにアップグレードするために使用できる、利用可能なOracleデータベースソフトウェアイメージが表示![zu01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/98b967e7-aa41-d6bc-27f5-55b4cced4bd6.png)
    - 「カスタム・データベース・ソフトウェア・イメージ」のタブでは、事前に作成したデータベース・ソフトウェア・イメージを選択
6. データベースのアップグレードに使用できるOracle提供またはカスタムのデータベースソフトウェアイメージのリストを確認し、アップグレードに使用するイメージを特定
7. アップグレードに使用するイメージの行で[アクション]（3つのドット）をクリック
8. 事前チェックをクリック(アップグレードを正常に適用できることを確認するための前提条件をチェック)![zu02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/c81511e2-0fe2-c552-61c8-8227c3c54e62.png)


事前チェックが完了を確認![zu03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/b53863a2-9359-d6aa-34d4-3e2442ccbf9a.png)

9. アップグレードをクリック(選択したデータベースのアップグレードを適用)![zu04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/7cd064ab-b66e-54b0-3b5f-d056a86f215b.png)
10. プロンプトが表示されたら確認し、[アップグレード]をクリック![zu05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/bacada11-21a3-0283-b082-3c420d43417b.png)
11. アップグレードが適用されている間、データベースのステータスは「アップグレード中」と表示![zu06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/c1b9adde-89f5-31b9-846d-aea0cdb8a83c.png)
12. アップグレード操作が正常に完了すると、データベースのステータスが[使用可能]に変わる![zu07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/9dc1dfc3-1779-0325-a44e-baac13f4da39.png)



##データベースのアップグレード履歴の表示
1. Webコンソールから > [データベース] > [ベアメタル、VM、およびExadata]をクリック
2. コンパートメントを選択
3. DBシステムのリストから履歴を表示したいシステム名をクリック
4. データベースのリストからデータベースの名前をクリック
5. リソースから[更新履歴]をクリック
6. そのデータベースのパッチおよびアップグレード操作の履歴が表示![zu08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/9e6ecb27-671e-9e2f-00ff-a05e35171ff0.png)



#おわりに
前提条件を満たしていて事前チェックが正常に完了しているデータベースをクリックだけで最新バージョンにアップグレードできた。
Djangoで動的にLINE Flex Messageを扱う際のベストプラクティス

どうもこんにちは！
初めてQiitaに投稿するので、軽く自己紹介を。
某情報連携学部に通う学生です。（某と言っても…）
好きなブラウザはFirefoxとEdge（Chromium）です。

さて、弊学部では一年生の後半に、全員が授業でDjangoを用いたチーム開発を行います。
私は昨年LINE botを作成したのですが、その際、DjangoでLINE Messaging APIのFlex Messageを動的に扱う上手いやり方が調べても出てこなかったので、個人的に考えたベストプラクティスを備忘録も兼ねてここに記します。
Flex Messageについては[こちら](https://developers.line.biz/ja/docs/messaging-api/using-flex-messages/#page-title)を参照。

# アプローチ
DjangoにはDjango Template Languageというテンプレート言語が用意されています。また、LINE Messaging APIのFlex MessageはJSON形式で記述します。
それらを用いて、Djangoサーバーがメッセージを送信する時に、雛形のJSONファイルに情報を埋めてFlex Messageを送るというアプローチを取りたいと思います。
（DjangoでHTMLファイルを扱う時と同じ感じですね）

#具体的な方法
DjangoでHTMLファイルに情報を埋めて送信するには通常`render()`などを使うと思いますが、これはHTTPレスポンスを行うものなので今回は使いません。代わりに`render_to_string()`を使います。

今回は以下の画像のように、送った文と日付をFlex Messageで表示するbotを例に挙げます。
![linebot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614288/5bc622e4-7fc5-2e24-9806-7d282180c0c4.jpeg)
なお、例に用いたmessage.jsonとviews.py全文は[GitHub Gist](https://gist.github.com/ryoheinan/d82fc6f4cd609013f3d4950ec609f72c)においてあります。

## コード例
LINE公式の[サンプルコード](https://github.com/line/line-bot-sdk-python)をDjangoに合わせて少し改変したものです。


```python
import json
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
from django.template.loader import render_to_string
from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.models import (
    MessageEvent, TextMessage, FlexSendMessage, BubbleContainer
)

#settings.pyからアクセストークンなどを取得（ここはお好みで）
line_bot_api = LineBotApi(channel_access_token=settings.LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(channel_secret=settings.LINE_CHANNEL_SECRET)

#（省略）

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    msg_text=event.message.text
    today_date = datetime.datetime.now()
    msg = render_to_string("message.json", {"text": msg_text, "date": today_date})
    line_bot_api.reply_message(
        event.reply_token,
        FlexSendMessage(alt_text = msg_text, contents = json.loads(msg))
    )
```

**重要なのはここです**

```python
msg_text=event.message.text
today_date = datetime.datetime.now()
msg = render_to_string("message.json", {"text": msg_text, "date": today_date})
```

templatesフォルダ下に置かれたmessage.jsonの`{{ text }}`の部分に、LINEに入力した内容である`msg_text`が、`{{ date }}`の部分に、現在日時である`today_date`が`render_to_string()`によって埋められるようになっています。

# まとめ
以上がDjangoで動的にLINE Flex Messageを扱う際の個人的なベストプラクティスになります。
お役に立ったらうれしいです。

# 参考
- [Django Template Language のドキュメント](https://docs.djangoproject.com/ja/3.1/ref/templates/language/)
- [render_to_string関数のドキュメント](https://docs.djangoproject.com/ja/3.1/topics/templates/#django.template.loader.render_to_string)
SPAとは？

#はじめに
最近SPA開発に興味を持ったので、簡単ではありますが、メリット・デメリットなどをまとめました。
（文字だらけですが・・・）

# SPAとは

「Single Page　Application」の略。単一ページ中でコンテンツの切り替えを行うWebアプリケーションのこと。

SPAを開発する上で、Vue.jsやReactなどのJavaScriptのフレームワーク・ライブラリを利用することが多い。

ブラウザでのページ遷移を必要とせずに新しい情報を読み込むことができる。

##### SPAの代表例

- slack Webページ
- Facebookメッセンジャー Webページ
- GoogleMap
- trello

など・・・

これらはWebではありますが、ページ遷移が無いので、スムーズに情報を閲覧できる。


#SPAのメリット

###①ユーザーのページ遷移ストレスが無くなる
ページのリロード（読み込み）が無いので、ページ遷移時にいちいちリロードされるのでユーザーにとってはストレスに感じる。
SPAは従来のWebサイトのように、ページ遷移ごとにページを丸々差し替える（新しいHTMLを表示させる）ことがなく、必要な部分のコンテンツのみ遷移させるので、画面全体が再描画されるストレスから解放される。

###②アプリのようなUX
SPAでは共通の部品は更新しないで、差分だけ更新するので、ユーザー一覧を表示したまま別の一覧ページさせたりすることができる。

###③開発の手間を省くことができる
SPAは幅広いUIを実装可能なので、iOSアプリやAndroidアプリのような端末内にダウンロードするネイティブアプリの代用として使用できる。
ネイティブアプリは`アプリのリリース前に審査を通過させる必要がある`、`デバイスごとの挙動を考慮する必要がある`というハードルがありますが、そういった問題を考慮せずに公開することができる。


#デメリット

###①初期ローディングに時間を要する
SPAは差分だけ更新させる動作をさせるので、フロントエンド側（JavaScript）で記述をするが、そのコード量が増加しがちなので、コードを読み込む時間がかかり、最初のページ読み込み時に時間がかかる。

###②実装コストがかかる
ブラウザ側に処理を任せていた部分を実装する必要があるので、特にフロントエンドの実装コストがかかる。

###③ネイティブアプリのようにモバイルのホーム画面に登録してもらい辛い
モバイルの場合、Webページをホーム画面に登録してもらえる機会が減る可能性が高い。普段使いには厳しいかも。

###④SPAが実装できるエンジニアがまだまだ少ない
国内だと、まだまだSPAはメジャーでは無いので、開発実装に対応できるフロントエンドエンジニアが少ない（少しずつ増えてきているのかも？？）


#どんなサービスに向いてる？
最初の読み込みは時間がかかるものの、初回読み込み後の各操作については更新のタイムラグが無い。そのため`ユーザー操作が多く、滞在時間が長いサービスがSPAに向いている`。
映画館や新幹線などのチケットの座席指定やグラフ・図などを用いたデータ可視化サービスなどに向いている。これらサービスは、検索が行われる度にページ遷移が発生し、頻繁に待ち時間が発生するのでSPA化することで、検索→結果表示が単一画面上で行われ、待ち時間を最小限に抑えることができる。

#どんなサービスが向いていない？
`滞在時間が長くないサービス、つまり直帰率が高い(１ページのみ閲覧して、ページから離脱してしまった割合）サービスはSPAに不向き`。
ブログなどの１ページのみのサイトなどが挙げられる。
直帰率の高いサービスにSPAを採用しても、最初のアクセス時に読み込み時間を多く要してしまうので時間がかかるばかりでメリットが感じられない。

「サービスの挙動を早くするためにSPAを採用したい！！」というのは少し考える必要がある。
SPAは同時に情報処理をすることは得意だが、データ更新が早くなるわけでは無いので、データ処理を早くするためにはバックエンドの構築を再考するのが良い。

#まとめ
SPAを採用する際はどういうサービスを開発したいのかを明確にして、SPAのメリット＆デメリットを考慮しながら導入していきたいところ。

#参考
https://digitalidentity.co.jp/blog/creative/about-single-page-application.html
https://www.oro.com/ja/technology/001/
[Rails]flashとflash.nowの違いについて！[初心者]

#flash[:notice]とは
主に``redirect_to``メソッドとセットで使用。
次のアクションまでエラーメッセージが表示されたままになる。

なお、``redirect_to``メソッドとともに使用する場合、引数に``notice``というキーを渡すだけで、フラッシュメッセージを表示することができます。

#flash.now[:notice]とは
主に``render``とセットで使用。
次のアクションに移行した時点で、エラーメッセージが消えてしまう。

#使用上の注意点
``render``とともに``flash[:notice]``を使用してしまうと、画面遷移後のページ(renderの次のアクションで表示するページ)にも、エラーメッセージが残ったままになってしまう。
逆に、``redirect_to``とセットで``flash.now[:notice]``を使っても、アクションを経由しているので、エラーメッセージが表示されない。

#使用例

```ruby:controllers/books.rb
class BooksController < ApplicationController
  def create
    @book = Book.new(book_params)
    @book.user_id = current_user.id
    if @book.save
      redirect_to books_path, notice: '投稿成功！！'  #notice:で引数を渡しているため、flashの記載は省略
    else
      flash.now[:alert] = "投稿失敗!!"
      render 'new'
    end
  end
end
```


#まとめ
以下のように使い分けるべし！！！！

````
redirect_to パス名, notice: "エラーメッセージ"
````

````
flash.now[:alert] = "エラーメッセージ"
render :アクション名
````
入力フォームの情報+複数枚の画像をバイト配列に変換する方法【Servlet/JSP】【MySQL】

#1.前提知識・条件
本記事では、Java、Servlet/JSP、MySQLなどの環境構築について、構築できている前提とするので省略します。
Java、Servlet,JSP、MySQLに関する基礎知識を前提としています。
必要となる知識
Java : リスト, イテレータ など
Servlet/JSP : GET/POST, データベースとの通信 など
MySQL : Javaのソース上でクエリを実行する方法 など

注意事項：冗長的なコードになっている可能性があるのでご了承ください。

#2.投稿のきっかけ
研修でServlet/JSP、MySQLを使ってWebアプリを構築することになり画像の処理が必要でした。
MySQLの方をMediumBLOB型にして、一枚の画像のみを格納・表示させる所までは、それなりに情報が載っており、比較的容易でした。
ですが、入力フォームのテキスト情報と一緒になった場合、画像を複数枚にした場合に情報が少なく行き着くまでにかなり苦労しました。
自分の備忘録としても、他の方の参考になれば良いかと思います(需要があるかは不明)。

#3.画像の保存
大まかな処理の流れは、下図のようになります。
![flow1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552271/1891379d-bf1a-1815-4335-9fd74151d9b6.png)
①Webブラウザ(JSPファイル)のフォームに情報・画像を登録
②送信ボタンが押されるとServletに登録情報が送信される
③Servletでデータを取得し、画像データをバイト配列に変換する
④DAOクラスを呼び出し、MySQLへ保存する
※本記事では④の処理を省略しています。
#4.テーブル構成
今回は簡単に画像名テーブルと画像テーブルの二つをサンプルとします(省略に省略を重ねています)。
画像を複数枚登録する場合は、画像名：画像 = 1:多になることを想定しています。

画像名テーブル

|nameId|name|
|:---:|:---:|
|varchar(4)|varchar(16)|
|Primary Key||

画像テーブル

|nameId|imageId|image|
|:---:|:---:|:---:|
|varchar(4)|varchar(4)|mediumblob|
||Primary Key||
#5.実際のコード
```Java:form.jsp
<form action="/test/RegisterServlet" enctype="multipart/form-data" method="post" name="reg" id="regform">
 <div>画像名<input type="text" name="imagename"></div>
 <div class="inputarea">画像
  <input type="file" name="file" id="ItemImage" multiple="multiple" accept="image/*" required >
 </div>
 <input type="submit" value="登録">
</form>
```
formタグ内でenctype="multipart/form-data"を指定することで、複数のデータ型を扱うことが出来る様になります。

```Java:RegisterServlet.java
//送信されてきた情報の取得
Collection<Part> pa = request.getParts();
//画像名用の変数を宣言
String name;


ArrayList<Part> regImg = new ArrayList<Part>();
//画像データをバイト配列に変換したとき用のリスト
ArrayList<byte[]> imgList = new ArrayList<byte[]>();

//拡張for文でCollection<Part>の中身をすべて取り出す
for(Part p : pa) {
 //要素のname属性名が"file"であった場合、画像データ用のリストへ格納
 if(p.getName().equals("file")) {
  regImg.add(p);
  } else {
  //画像以外である場合、nameに値を格納
  name = request.getParameter(p.getName()); // ※１
  }
 }

//画像データ格納用のリストの中身をすべて取り出す
for(Part p : regImg) {
 //FileInputStream型にキャストする
 FileInputStream fis = (FileInputStream) p.getInputStream();
 //readAllBytesメソッドでbyte配列に変換する
 byte[] bytes = fis.readAllBytes();
 //byte配列用のリストに格納する
 imgList.add(bytes);
 }
 //DAOメソッドの呼び出し
}
```

enctype="multipart/form-data"で送られてきたデータはPart型で送られます。
複数のデータを送った場合は、request.getPartsメソッドでCollection<Part>型の変数に格納できます。

※１
今回は画像名だけなのでelse文以下は、「name = request.getParameter(p.getName())」だけになっています。
画像名以外のテキストも登録される場合は、HashMap<String, String>などを宣言して(p.getName(), request.getParameter(p.getName())で(name属性, パラメータ)の様にセットで格納しておくとよいでしょう。

#6.まとめ
いかがだったでしょうか。
本記事では、ブラウザから送られてきたテキストと画像データをServletで受け取ってバイト配列に変換する方法を記述しました。
バイト配列に変換してしまえばデータベースの登録は比較的容易なので省力しています。
需要あるか分かりませんが、私と同じ事考えていて、困る人が少しでも減ったら幸いです。
[Rails][ransack] link_toで検索条件を作り、classをつける

link_toにclassをつけるのに苦戦したので備忘録もかねて。

ransackで検索機能を作っており、あるdivをクリックした時にあらかじめ決めておいた検索結果にリンクさせようとlink_toを使い苦戦。

##最初に書いていたコード
```erb
<%= link_to  controller: "shops", action: "index", q: { name_cont: '東京'}, class: "反映させたいクラス" do %>
 <div>このdivをクリックしたら「東京」の検索結果にとぶ</div>
<% end %>
```
[こちら](https://teratail.com/questions/68589)を参考に書きました。やってることはほぼ同じで、リンクテキストを踏ませるかdivを踏ませるかの違いです。
リンクテキストを指定する代わりにdo endで囲んでブロックにし、`controller: ~ 東京 }`までがパスで、その後にclassを書いているというイメージです。

エラーは出ずリンクは機能するものの、classが反映されず...

##うまくいったコード
```erb
<%= link_to ({ controller: "shops", action: "index", q: { name_cont: '東京' }}, { class: "反映させたいクラス" }) do %>
 <div>このdivをクリックしたら「東京」の検索結果にとぶ</div>
<% end %>
```

最初に書いていたコードも文法的には間違いではないそうですが、classとパスの境目が曖昧でclassもURLの一部と見なされていたようなので、URL部分とその他の部分でハッシュを分けたらうまくいきました。
symbol-cliを触ってみたその4

# 少しずつ復活してきました。
ちょっといろいろな事情があって活動できなかったのですが、
いろいろな人のご協力の元少しずつ復活してきました。

またsymbolのことについて記載していますが、そんなに理解はしていません。
あくまでも触ってみたの記事です。
ですので詳しい解説などsymbol賢者の方がおられましたらコメントなどでいただけますと幸いです。

今日はsymbol-cli chainについて

このchainで取得できる要素は3つ

・height

・info

・score

の3つです。

さてchainが何を引っ張ってくるのかはピンときていませんがみていきましょう。

## height

実行するとこんな感じになりました。

```
(base) ~% symbol-cli chain height
157546
```

おそらくですが、現在のノードの最新の情報を取得するのかもしれません。
そしてheightなので最新のブロック高を取得するようなイメージかもしれません。

## info

実行結果はこちらです。

```
(base) ~% symbol-cli chain info  

Chain Information
┌────────────┬─────────────────────┐
│ Property   │ Value               │
├────────────┼─────────────────────┤
│ Height     │ 157547              │
├────────────┼─────────────────────┤
│ Score Low  │ 2963559831726209428 │
├────────────┼─────────────────────┤
│ Score High │ 0                   │
└────────────┴─────────────────────┘ 
Latest Finalized Block
┌────────────────────┬──────────────────────────────────────────────────────────────────┐
│ Property           │ Value                                                            │
├────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Finalized Height   │ 157032                                                           │
├────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Finalized Hash     │ A1CB3A2CCBC2A15EF9B971A6349CDEC74899A7425FE5CE38086D227BEE517BE2 │
├────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Finalization Point │ 4                                                                │
├────────────────────┼──────────────────────────────────────────────────────────────────┤
│ Finalization Epoch │ 4                                                                │
└────────────────────┴──────────────────────────────────────────────────────────────────┘
```

謎の言葉としてScore LowとScore High
そしてFinalizedという言葉。

これは一体何を意味しているのでしょうか。分かる方おられましたらコメントいただけますと幸いです。

https://docs.symbolplatform.com/ja/concepts/block.html#finalization

こちらにファイなライゼーションについての記述がありました。

要するにブロックの記述として確定されたものとして認識すればいいのかと思います。
このファイナライゼーションがブロックチェーン台帳の変更を確定させてそれを永続的にするプロセスと書いています。

なので一番最新のファイナライズされた情報でそのハッシュとかもみれますよということかな？
## score

実行結果がこちら

```
(base) ~% symbol-cli chain score

Storage Information
┌────────────┬─────────────────────┐
│ Property   │ Value               │
├────────────┼─────────────────────┤
│ Score Low  │ 2963559831726209428 │
├────────────┼─────────────────────┤
│ Score High │ 0                   │
└────────────┴─────────────────────┘
```

先ほどのinfoの情報の中からscoreのみを抽出した感じになりました。

スコアについてはこちらに記述がありました。
https://docs.symbolplatform.com/ja/concepts/consensus-algorithm.html#scores

ネットワークは各要因を全ての高価値アカウントに対して以下のサブスコアを計算します。

ただこのScore LowやHighが何を意味しているのか？

もしSymbol賢者の方がおられましたらコメントにて解説していただけますと幸いです。
programmingError line 1: select count(*) as "__count" from "chat_chat"的なやつを治す方法

superuserでadminにログインし、モデルの一つのChatを開こうとしたら起こった。

記事を漁ると、migrationとかpyhacheあたりを削除して、もう一回

```
>>> python manage.py makemigrations
>>> python manage.py migrate
```
をすれば治るらしい。

ただ治らない。

１．appもう一個作る。
もう一個、

```
>>> python manage.py startapp chats
```
でアプリを作って全部コピペ。
今回はこれで解決。

２．新しいデータベースを作る。

試してないけどこれが一番早いかも。


３．今あるデータベースを初期化してmakemigrations

userまた作んのめんどいから避けたけど、1番もそこそこ時間かかるので次はこれを試したい。
WSLからAnsible WinRM接続ができなくなった件

AnsibleはWindowsでは動かないので、WSLの中でAnsibleを実行してホスト側のWindowsにWinRM接続するようにしていたのだが、久し振りにやってみたらConnection Refusedが出て接続できなかった。

WinRMの設定をいろいろ変えて試してみたが、どうしてもできない。原因は別のところにあった。

WSLをWSL2に変えたせいで、WSL2の中からWindows側のポートにアクセスできなくなっていたのだ。
どうも、WSL2の中からlocalhostやマシン名指定でWindows側のポートにはアクセスできないらしい。
192.168.～とIP直打ちならいけるけど、DHCPなんでIPは変わる可能性があるんだよなぁ。

追記：マシン名.local だと大丈夫だった。
[UE4] "コードファイル D:¥Build¥++UE4+Licensee¥xxx が見つかりません" の解消方法

![スクリーンショット 2020-11-19 18.27.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44103/bd3be5ba-4441-1bed-b1c1-2f2fe79605b6.png)

UE4をデバッグしようとして、デバッグシンボルを有効にしたり、ソースコードを入手しても、実際にC++ Symbolsを表示させようにも上記エラーで解決できないことがある。

## 1. まずエラーで表示されているパスを確認

表示されるのが一瞬なので、スクリーンショットを撮るのがおすすめ。

4.25.4 が最新の2020年11月現在では、表示されるパスは `D:¥Build¥++UE4+Licensee¥Sync` や `D:¥Build¥++UE4¥Sync` など、

- なぜか必ず **Dドライブ** を示していて
- **++UE4** とか **Sync** とかの文字列が入っている

のが特徴。このパスは、Epic Gamesが配布版のUE4をビルドしたときに指していたパスと言われていて、配布版のバイナリの場合は変更することはできないらしい。

**自分でビルドしたUE4であればそもそも上記エラーは出ない**のだが、以下で示す解決法は、自分でUE4をビルドすることなく、**指しているパスを再現**することで解決する方法。

## 2. Dドライブを物理的 or 仮想的に準備

既にDドライブが存在する人は飛ばして次へ。

ない人は物理的に準備するか、以下の方法で仮想的に作る。

- エクスプローラーでCドライブ直下に `VirtualDDrive` というフォルダを作り
- コマンドプロンプトを管理者権限 **なしで** 開き
- `subst D: C:¥VirtualDDrive` を実行

こうすると、仮想的にDドライブができ、Cドライブ直下に作った `VirtualDDrive` というパスを指すようになる。

ただしsubstコマンドの効果は再起動すると消えてしまうので、上記内容のbatファイルを作ってスタートアップフォルダに入れておくと解決する。詳しくは[別のQiita記事](https://qiita.com/y_minowa/items/c86bd98e2b0b33459ce6#%E5%95%8F%E9%A1%8C%E7%82%B9)などを参照。

## 3. Syncまでのフォルダを作成

次に先程準備したDドライブに、Syncフォルダまでのフォルダをエクスプローラーで作成する。パスは控えておいたエラーメッセージの通りにする。

例えば `D:¥Build¥++UE4+Licensee¥Sync`と表示された場合は、Dドライブに`Build`、その中に`++UE4+Licensee`フォルダを作る。

ただしSyncフォルダ自体は次の作業でリンクを作るので、作らないでOK。

## 4. SyncフォルダとUE4のソースコードをリンクさせる

コマンドプロンプトを開いて**ジャンクション** (または**シンボリックリンク**) を作成する。

例えばエラーメッセージに `D:¥Build¥++UE4+Licensee¥Sync` と出ていて、UE4のソースコードが `C:¥UE_4.25` にある場合は、

```
mklink /J D:¥Build¥++UE4+Licensee¥Sync C:¥UE_4.25
```

をコマンドプロンプトで実行する。（管理者権限が必要な場合がある。）

これで、擬似的にエラーメッセージに出ていたパスが再現されるので、改めて実行するとエラーは起きない。

もちろん、ジャンクションやシンボリックリンクでなくても、物理的にそのフォルダにソースコードを移動させてもOK。

## 補足: 何かと便利なシンボリックリンク

ちなみにジャンクションやシンボリックリンクを作る方法はいろいろと便利で、Visual Studio内でUE4のパスが上手く参照されないときの暫定的な解決法にもなるし、容量が大きいフォルダを別のドライブに移してシンボリックリンクで元の場所にあるかのように振る舞わせたりすることができる。

ただし、ジャンクションやシンボリックリンクを削除するときは、うっかり元のフォルダの中身が消えてしまわないように細心の注意が必要（unlinkやrmdirなどを使って消す）。
言語を自作してみた(2)

# 自作言語のお時間です
最近寒すぎて凍死しそうです、、、、
## また作りました
はい、アップデートしました。主な変更点としては、

- エラー機能/エラーも自作しました。自作しないとあんま愛着がわかないんですよね。
- class/なんちゃってですけど遂にクラスを実装しました。オブジェクト思考、万歳！
- printしたときになぜか空白が出るのを何とかして無くしました。
- ファイル数が格段に少なくなりました。
- そのおかげで実行が軽くなりました！

そんなOmega-version0.1.0はこちらから(Github)
->https://github.com/pythonmaster1027/Omega-version0.1.0

# とりまコード

ファイル階層

```
(任意のディレクトリ)
 ├ main.py
 └ Omega.bat
```

コードがめっちゃ少なくなりました。

```python:main.py
import os
import sys

class Start:#startして欲しいので

    def __init__(self):#初期化
        try:
            self.f = open(sys.argv[1], "r", encoding="utf_8")
        
        except IndexError:
            print("ファイル名を指定して下さい")
            sys.exit()
        
        except FileNotFoundError:
            print("ファイルが見つかりません")
            print("解決するには：ファイルパスをフルパスにする")
            sys.exit()
        
        self.r = self.f.readlines()
        self.re = self.f.read()
        self.dic1 = {}

    def run(self):#runしてほしいので

        if "class Main{\n" in self.r:
            for line in self.r:
                line = line.replace("    ", "").replace(" ", "").split("//")[0]#line = self.fから一行ずつ読み込まれたプログラム
                
                #print
                if "print" and '"' in line:
                    pr = line.replace("print", "").replace("{", "").replace("}", "").replace('"', "")
                    print(pr)
                
                #変数の定義
                elif line.startswith("int") or line.startswith("str"):
                    self.var = line.replace('\n', "")
                    varname = self.var.split("=")[0]#変数名
                    if line.startswith("int"):
                        try:
                            self.ele = eval(self.var.split("=")[-1].replace("int", ""))#int型の要素
                        except NameError:
                            print("Err: NameErr")
                            self.ele = "Not int"
                    elif line.startswith("str"):
                        self.ele = self.var.split("=")[-1].replace("str", "")#int型の要素
                    self.dic1[varname] = self.ele
                    
                #引数に変数を指定するprint
                elif "print" in line:
                    line = line.replace("print", "").replace("{", "").replace("}", "").replace("\n", "")
                    print(self.dic1[line])

                elif line in "\n":
                    pass
        else:
            print("Err: クラス[Main]が見つかりません")
            sys.exit()

#実行関数の定義
def main():
    s = Start()
    s.run()

#実行部
if __name__ == '__main__':
    main()

```
pythonコード、これだけです。たったの。次、Omega.bat.

```batch:Omega.bat
@echo off
main.py %1
```
# まとめ
この言語、ファイル実質2ファイルだけで構成されてるんです。とゆーか2ファイルだけで言語作れんのってすごい。
次は関数定義も実装したいと思います。
NUCで始めるVMware Tanzu - Nested ESXi

本日は、Nested ESXiを紹介します。Nestedとは、「入れ子の」という意味で、ESXiの中にESXiを入れてしまおうというお話です。
なんでそんなことをするかというと、仮想化するとNICが作り放題というメリットがあります。NICを作りたい背景として、vSphereでは、vMotionとかvSANを行いたい場合、ネットワークを分ける必要があるため、検証用途では大変重宝します。
注意点として、余分にESXiを入れる分、余計なオーバーヘッドが発生するため、Nestedしなくてもなんとかなる場合は、あえてしない方が良いでしょう。当然、本番環境では非推奨なので、基本的には、物理的なNICを増やすよう調達する方向でがんばりましょう。

#ESXiメディアのアップロード
最初に、先日ダウンロードしたESXiのISOを、各ESXiにアップロードします。データストアブラウザを起動して下さい。
![スクリーンショット 2020-11-08 17.35.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/0495d574-1231-14af-9889-583cf6733108.png)
アップロードボタンを押して、ローカルのメディアを選択してしばらく待つと、下図のように設置されます。
![スクリーンショット 2020-11-08 17.58.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/3561b377-5c57-0b0f-271a-d8846029b6bf.png)

#ESXiのインストール
まずは、仮想マシンのメニューから、「仮想マシンの作成／登録」をクリック
ウィザードが立ち上がります。「新規仮想マシンの作成」で、「次へ」
![スクリーンショット 2020-11-08 17.01.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/3b43a58a-3b95-0dc5-5b67-e9d1b1b6a5dc.png)
名前を入力し、ゲストOSファミリとバージョンを下図のように変更。次へ。
![スクリーンショット 2020-11-08 17.02.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/4eb43f09-5921-4be2-391d-51230008e8b6.png)
ストレージ選択。データストアを選択して、「次へ」。
![スクリーンショット 2020-11-08 17.03.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/7acb93b2-9d81-eb1a-6a4e-a2dfa9e76005.png)
設定のカスタマイズ。いくつか設定を変更した

- CPU: 4
- ソケットあたりのコア：1
- 「CPUホットアドの有効化」にチェック
- 「ハードウェアアシストによる仮想化をゲストOSに公開」にチェック
- 「IOMMUをゲストOSに公開」にチェック
- メモリ：３２GB
- ハードディスク：１台目は６００GB、２台目以降は300GB
- USBコントローラ：USB3.1
- ネットワークアダプタ：VM Network
- CD/DVDメディア:先ほどアップロードしたISOファイルを選択
![スクリーンショット 2020-11-08 17.28.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/1cb2e66b-bf90-d0d1-3ed8-db15fb6f3ee3.png)
確認画面。そのまま完了
![スクリーンショット 2020-11-08 17.28.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/7c62636b-0227-044e-51bc-0e04a7984e66.png)
はい、出来上がりました。VMware Toolsをインストールしておきます。
![スクリーンショット 2020-11-08 17.30.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/bb9681a6-e308-1c9e-2863-5020d2799664.png)
続いて、パワーオン。後は、基本的にはESXiのインストール方法と一緒です。
![スクリーンショット 2020-11-08 18.00.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/5a3352f2-db0e-0646-eb32-4aad7741523f.png)
Macの場合、F11が押せないので、メニューから「キーの送信」を押すことができます。
![スクリーンショット 2020-11-08 18.02.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/5fc2c829-6123-9f70-4e74-4a47ca616951.png)
はい、無事にNestedなESXiが作れました！
![スクリーンショット 2020-11-08 18.19.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18601/9ccf1728-c890-4bef-54b8-1012647b92eb.png)

はい、本日は終了です。
kusanagiのAMI ID を AWS CLI で調べて、一撃で起動したい

Kusanagiの最新のAMI IDをCLIで確認してCLIからEC2を起動したい( 2020/11 時点 )

※ AWSマーケットプレイスの ProductCodeId の運用については、オフィシャルがアナウンスしている訳ではないので注意が必要だと思います。将来的に変わる可能性もあるかと。

# AWSマーケットプレイス内を『KUSANAGI』で検索

```
aws ec2 describe-images --region ap-northeast-1 --owners 'aws-marketplace' --filters --filters 'Name=name,Values=*KUSANAGI*' | jq .
```

出力内容をみると...

ProductCodeId は
* 239igp26xilrqtgegz3yqea8h
* f18wc0igqjhsxwoxouogwqb8m 
の2つあり...
`f18wc0igqjhsxwoxouogwqb8m` の方が起動したい `KUSANAGI for AWS (WordPress)` を含んでいました。

![スクリーンショット 2020-11-19 20.52.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124921/9abef1f5-d65d-c5ee-d0d3-231b748c1a74.png)

# 「最新のイメージ」かつ「無償のマシンイメージ」のAMI IDを取得したい

```
aws ec2 describe-images --region ap-northeast-1 --owners 'aws-marketplace' --filters --filters 'Name=product-code,Values=f18wc0igqjhsxwoxouogwqb8m' --query 'sort_by(Images, &CreationDate)[-1].[ImageId]' --output 'text'
```

[CentOSの例ですが、ここを参考にしました](http://www.hosty.uk/aws/finding-an-ami-id-using-aws-cli-in-aws-marketplace/) 
( [CentOSの場合は、こんな感じでプロダクトコードを公開してくれてるんですよね](https://wiki.centos.org/Cloud/AWS) )


--query で日付ごとにソートし、
--output 'text' でシンプルなテキストのみを取得しています。

また --filters で使えるオプションは[ここが参考になりそうです](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-images.html#options)

# AWS CLI で一発起動
最後にjqでパースしてIPアドレスを返します( sshでログインする設定を作るので欲しい )

```
aws ec2 run-instances --profile AWSプロファイル名 \
--count 1 \
--subnet-id サブネットID \
--security-group-ids セキュリティグループID \
--instance-type t2.medium \
--image-id $(aws ec2 describe-images --region ap-northeast-1 --owners 'aws-marketplace' --filters --filters 'Name=product-code,Values=f18wc0igqjhsxwoxouogwqb8m' --query 'sort_by(Images, &CreationDate)[-1].[ImageId]' --output 'text') \
| jq --raw-output '.Instances[0].NetworkInterfaces[0].PrivateIpAddress'
```
ハンバーガーメニューを開いても背景が透けない！？

ハンバーガーメニューを開いた際に、なぜか背景が透けなかったので原因を分析してみました。

元のコード
---

```html:index.html
<span class="nav-menu">
        <i class="nav-menu-i"></i>
        <i class="nav-menu-i"></i>
        <i class="nav-menu-i"></i>
      </span>
      <nav class="nav">
        <ul class="header-nav">
          <li class="header-nav-list"><a href="#"></a></li>
          <li class="header-nav-list"><a href=""></a></li>
          <li class="header-nav-list"><a href=""></a></li>
          <li class="header-nav-list"><a href=""></a></li>
          <li class="header-nav-list"><a href=""></a></li>
          <li class="header-nav-list"><a href=""></a></li>
        </ul>
      </nav>
```


```css:stylesheet.scss
.nav {
  position: relative;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .5s, visibility .5s
}

.nav.show {
  opacity: 0.9;
  visibility: visible;
  background-color: white;
}

.nav-menu {
  display: block;
  position: relative;
  position: absolute;
  position: fixed;
  width: 1.75rem;
  height: 1.5rem;
  top: 10px;
  right: 10px;
  cursor: pointer;
  z-index: 100;
  .nav-menu-i {
  display: block;
  width: 100%;
  height: 2px;
  background-color: black;
  position: absolute;
  transition: transform .5s, opacity .5s;
  }
  .nav-menu-i:nth-child(1) {
  top: 0;
  }
.nav-menu-i:nth-child(2) {
  top: 0;
  bottom: 0;
  margin: auto;
  }
.nav-menu-i:nth-child(3) {
  bottom: 0;
  }
}

```

Sassの書き方が汚いのはご愛嬌で…

nav-menu-iはハンバーガーの線を表しています

navを開いても、背景が透けてくれず、困ってたのですが、、

```css:stylesheet.scss
.nav {
  position: relative;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .5s, visibility .5s;
  z-index: 99;
}

```

z-indexを指定してあげると解決しました！
positionを使っているので、重なり順を指定してあげると解決するみたいですね🤔
URLの構成要素の名前と部分別の呼称メモ

# URL/URI
```
スキーム://[サブドメイン].ドメイン:ポート/パス?クエリパラメータ名=クエリパラメータ値#フラグメント
------------{---------FQDN-------}
{-----------------Origin-------------}
```

## 定義
https://tools.ietf.org/html/rfc2396

# スキーム
* http
* https
* file
* etc...

### 同義語
プロトコル

# ドメイン
ネットワーク上のホストを指す。IPと一対一。
実体は、アドレスを持ちうるサーバ、ロードバランサー、コンテナなどなど。

## サブドメイン
ドメイン下における仮想ドメイン。IPとしてはドメインと同一。
リクエスト先を制御したい場合、サブドメインを分けて管理する場合がある。
実体は、アドレスを持ちうるサーバ、ロードバランサー、コンテナなどなど。

### 同義語
ホスト

# FQDN
`[サブドメイン|ホスト].ドメイン`を指したもの。


# ポート
TCPポート。

# Origin
`スキーム://[サブドメイン].ドメイン:ポート`
djoserでsuperuserを作る方法

とりあえずこの記事の通りにやる。
https://qiita.com/KueharX/items/009687407fa0c542839a

しかし、curlでAPIたたいても、"detail":"Authentication credentials were not provided."のエラーが起こるので、http://localhost:8000/auth/jwt/create/
で直接ログインした後に、adminに行って、ログイン。

```models.py
class UserAccountManager(BaseUserManager):
    def create_user(self, email, name, password=None, **extra_fields):
        if not email:
            raise ValueError('User must have an eamil address')

        email = self.normalize_email(email)
        user = self.model(email=email, name=name, **extra_fields)

        user.set_password(password)
        user.save()

        return user #'NoneType' object has no attribute 'is_active'

    def create_superuser(self, email, name, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have true value of is_staff')

        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have true value of is_superuser')

        return self.create_user(email, name, password, **extra_fields)
```

```
return self.create_user(email, name, password, **extra_fields)
を
return self.create_user(self,email, name, password, **extra_fields)
にしないように注意。コピペしてやるとやりがちなので。
[SQL] 特殊なデータ取得

昨日に引き続きSQLの記事です。
データ取得の続きについて書きます。

#特定の文字や数値を含むデータの取得
以下のテーブルを例に挙げて考える。

テーブル名:menue

|number|name|price|category|
|:---:|:---:|:---:|:---:|
|1|ショートケーキ|200|デザート|
|2|チョコケーキ|250|デザート|
|3|コーヒー|120|ドリンク|
|4|チョコマフィン|150||
|5|コーヒーゼリー|150|デザート|

##LIKE演算子とワイルドカード
###LIKE演算子
「ある文字を含むデータ」を取得したい場合に用いる。
「～のような」という意味を持つ。

「指定したカラムが〇〇を含むレコード」という条件となる。

###ワイルドカード
「どんな文字列にも一致することを指す記号」のこと
「%」を用いる。

以下の表に条件と記述法を表す。

|条件|記述|
|:---:|:---:|:---:|
|全一致|"%文字列%"|
|前方一致|"文字列%"|
|後方一致|"%文字列"|

```sql
SELECT カラム名
FROM テーブル名
WHERE カラム名 LIKE 文字列;
```
【全一致の場合】

```sql:sample1
SELECT *
FROM menue
WHERE name LIKE "%ケーキ%";
```
|number|name|price|category|
|:---:|:---:|:---:|:---:|
|1|ショートケーキ|200|デザート|
|2|チョコケーキ|250|デザート|

【前方一致の場合】

```sql:sample2
SELECT *
FROM menue
WHERE name LIKE "チョコ%";
```
|number|name|price|category|
|:---:|:---:|:---:|:---:|
|2|チョコケーキ|250|デザート|
|4|チョコマフィン|150||

【後方一致】

```sql:sample3
SELECT *
FROM menue
WHERE name LIKE "%ケーキ";
```
|number|name|price|category|
|:---:|:---:|:---:|:---:|
|1|ショートケーキ|200|デザート|
|2|チョコケーキ|250|デザート|

##条件を満たさないデータを取得
###NOT演算子
「〇〇を含まないデータ」や「〇〇に一致しないデータ」のような条件で
データを取得したい場合に用いる。「否定」を意味する。

```sql
SELECT カラム名
FROM テーブル名
WHERE NOT カラム名 LIKE 文字列; 
```
```sql:sample3
SELECT *
FROM menue
WHERE NOT name LIKE "%ケーキ%";
```
|number|name|price|category|
|:---:|:---:|:---:|:---:|
|3|コーヒー|120|ドリンク|
|4|チョコマフィン|150||
|5|コーヒーゼリー|150|デザート|

また、条件に比較演算子と数値を指定することも可能。

```sql
SELECT カラム名
FROM テーブル名
WHERE NOT カラム名　比較演算子　数値; 
```
```sql:sample4
SELECT *
FROM menue
WHERE NOT price > 200; 
```
このときの条件は、「priceが200より大きい (満たす)」を否定しているため
「priceが200より小さい(200以下)」という条件になる。
ちょっとややこしいですが...汗

|number|name|price|category|
|:---:|:---:|:---:|:---:|
|1|ショートケーキ|200|デザート|
|3|コーヒー|120|ドリンク|
|4|チョコマフィン|150||
|5|コーヒーゼリー|150|デザート|

##カラムに何も保存されていないデータの取得
###NULL
「中身がなにか分からない状態」のこと
データベースでは「何のデータも保存されていない場合」に用いる。

###IS NULL
「指定したカラムがNULLであるデータ」を取得する場合に用いる。
「～がNULLである」という意味を持つ。

```sql
SELECT カラム名
FROM テーブル名
WHERE カラム名 IS NULL;
```
```sql:sample5
SELECT * FROM menue
WHERE category IS NULL;
```
|number|name|price|category|
|:---:|:---:|:---:|:---:|
|4|チョコマフィン|150||

###NOT IS NULL
「指定したカラムがNULLでないデータ」を取得する場合に用いる。
「～がNULLでない」という意味を持つ。

```sql
SELECT カラム名 
FROM　テーブル名
WHERE カラム名 NOT IS NULL;
```
```sql:sample6
SELECT * FROM menue
WHERE category NOT IS NULL;
```
|number|name|price|category|
|:---:|:---:|:---:|:---:|
|1|ショートケーキ|200|デザート|
|2|チョコケーキ|250|デザート|
|3|コーヒー|120|ドリンク|
|5|コーヒーゼリー|150|デザート|
マイグレーションファイルのカラムを削除するには

今回はマイグレーションファイルを作成した後に、「あれ？このカラム使わないな、」と思った時にカラムを削除する方法を紹介したいと思います。
#1. 仮のマイグレーションファイルを作成する
```
マイグレーションファイルを作る際のコマンド

rails generate migration Add（カラム名）To(テーブル名) (カラム名）：データ型

```

##　筆者の例として
usersテーブルにstring型のnameカラムとimageカラムを作成したとします。

```
rails g migration AddNameToUsers name:string　image:string
```

このコマンドを打つと下記のようなマイグレーションファイルが作成されます。

```
class AddColumnsToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :name,  :string
    add_column :users, :image, :string
  end
end
```

#2. カラムの削除
```
マイグレーションファイルを削除する際のコマンド

rails generate migration Remove（カラム名）To(テーブル名) (カラム名）：データ型

```
とコマンドを打つとカラムを削除するための新たなマイグレーションファイルが作成されます。

開発を進めていく中でimageカラムやっぱりいらないな、と思ったら

```
rails g migration RemoveNameToUsers　image:string
```
と打つことで

```
class RemoveColumnsToUsers < ActiveRecord::Migration[5.2]
  def change
    remove_column :users, :image, :string
  end
end
```
というマイグレーションファイルができます。
この後は

```
rails db:migrate
```
と打つことで無事usersテーブルのimageカラムは消えています。スキーマを確認してもらえるとカラムが消えているのが確認しやすいです。

#番外編. 間違えて削除のコマンド打ってしまった場合の対処法（筆者の失敗例をもとに）


筆者が実際に削除用のマイグレーションのコマンドを打ち間違えてしまい

```
rails g migration RemoveNameToUsers
```
と打ってしまいできてしまったマイグレーションファイルがこちらです↓

```
class RemoveColumnsToUsers < ActiveRecord::Migration[5.2]
  def change
  end
end
```
削除用のカラムが記載されていないファイルができてしまいました・
このファイルは削除しないといけません。まずは削除できる状態にあるか確認をします。


```
bundle exec rake db:migrate:status
```
このコマンドを打つとstatusがupになっていると思いますがこの状態だと削除することができません。
upをdownに変えてあげて削除できる状態にします。

```
bundle exec rake db:migrate:down VERSION=MigrationIDから始まるファイル名を入れる
```
これでいまstatusがdownになっているのであとは

```
rm -rf db/migrate/MigrationIDから始まるファイル名を入れる
```
これでマイグレーションファイルの削除が完了したのでこの記事のカラムを削除するマイグレーションファイルを作成するところから初めて行けば大丈夫です。

いかがだったでしょうか？ぜひ参考にしていただけると幸いです！