20200526のMySQLに関する記事は9件です。

【環境構築】Windows10にXAMMPをインストール方法

Xamppのインストール方法をご紹介します。画像多めです。

作業環境

OS:Windows 10
エディション:HOME
バージョン:2004

XAMPPのインストール方法

①公式サイトからダウンロード

下記の公式サイトにアクセスします。
https://www.apachefriends.org/jp/index.html
202005262113.png
「Windows向けXAMPP」をダウンロードします。
執筆時点(2020/05/26)では、バージョンは7.4.6です。

②インストールする

ダウンロードが完了したら、ファイルをダブルクリックしてインストールします。基本的にこだわりがなければ、「Next>」を押していくだけです。
202005262117.png
セットアップの最初の画面です、「Next>」を押します。
202005262118.png
Components(構成要素)を選びます。特に怪しいものはないので、「Next>」を押します。
202005262119.png
インストールするフォルダを選びます。Cドライブ直下で問題ない場合は、そのまま「Next>」を押します。
202005262214.png
言語の選択の画面です。日本語は選べないので、そのまま「Next>」を押します。
202005262215.png
チェックボックスのチェックを外して、「Next>」を押します。
202005262216.png
インストールの準備ができたので、「Next>」を押します。
202005262227.png
インストールが始まります。
202005262228.png
完了したら、「Finish」を押してインストール完了です。
202005262254.png
インストールが完了したら、上記の画面が表示されます。
特に難しい点などはなくインストールできますが、ポートの競合などが起こる場合があるので、設定については別記事にて解説します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【環境構築】Windows10にXAMMPをインストールする方法

XAMMPのインストール方法をご紹介します。画像多めです。

作業環境

OS:Windows 10
エディション:HOME
バージョン:2004

XAMPPとは

XAMPPとは
X → Cross platform(MacでもWindowsでもLinuxでも利用できる)
A → Apache(Webサーバー)
M → MariaDB(データベース)
P → PHP(プログラム言語)
P → Perl(プログラム言語)
の略で、ウェブアプリケーションの実行に必要なフリーソフトウェアをパッケージとしてまとめたものです。
つまり、XAMMPを1つをインストールするだけで、アプリを作成する環境が構築できるのです。
PHPはブラウザだけでは動かないので、PHPを動かすために導入しています。

XAMPPのインストール方法

①公式サイトからダウンロード

下記の公式サイトにアクセスします。
https://www.apachefriends.org/jp/index.html
202005262113.png
「Windows向けXAMPP」をダウンロードします。
執筆時点(2020/05/26)では、バージョンは7.4.6です。

②インストールする

ダウンロードが完了したら、ファイルをダブルクリックしてインストールします。基本的にこだわりがなければ、「Next>」を押していくだけです。
202005262117.png
セットアップの最初の画面です、「Next>」を押します。
202005262118.png
Components(構成要素)を選びます。特に怪しいものはないので、「Next>」を押します。
202005262119.png
インストールするフォルダを選びます。Cドライブ直下で問題ない場合は、そのまま「Next>」を押します。
202005262214.png
言語の選択の画面です。日本語は選べないので、そのまま「Next>」を押します。
202005262215.png
チェックボックスのチェックを外して、「Next>」を押します。
202005262216.png
インストールの準備ができたので、「Next>」を押します。
202005262227.png
インストールが始まります。
202005262228.png
完了したら、「Finish」を押してインストール完了です。
202005262254.png
インストールが完了したら、上記の画面が表示されます。
特に難しい点などはなくインストールできますが、ポートの競合などが起こる場合があるので、設定については別記事にて解説します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Azure Database for MySQLでレプリケーションによるデータ移行+バージョンアップをして得たこと

はじめに

今回案件でAzure Database for MySQLでのレプリケーションを検証したため、その中で得たノウハウを書き留めておきます。
OSSとしてのMySQLのレプリケーションノウハウは他にもたくさん記事があるのでAzureのマネージドサービスに特化した内容にします。

今回お客様からの要件は以下でした。

  • Azure Database for MySQL 5.7からAzure Database for MySQL 8.0へのアップグレード
  • 極力サービス停止時間を短くデータ移行
  • 異なるリージョン間での移行

まず移行方式としてはExport/Importもありますが、今回はサービス停止時間を短くするためにレプリケーションによる移行としています。

Azure Database for MySQLでレプリケーションを実現するには手段が3つあります。
2つ目、3つ目が公式ドキュメントにPaaSとしてのレプリケーション機能っぽく記載されています。

  • OSSとしてのMySQLのレプリケーション機能

  • データインレプリケーション
     Azure Database for MySQLをスレーブとして利用するための機能

  • 読取レプリカ
     Azure Database for MySQLをマスタとして利用するための機能

それぞれをMySQL(OSS)のレプリケーションで実施する作業をベースに比較してみます。

手順 実行ノード  OSS  データインレプリケーション 読取レプリカ
バイナリログ有効化 マスタ 手動 手動 自動
レプリケーション用ユーザ作成、権限付与 マスタ 手動 手動 自動
読み取り専用 マスタ 手動 手動 自動
バイナリログの位置確認 マスタ 手動 手動 自動
マスタのDump取得 マスタ 手動 手動 自動
読み取り専用解除 マスタ 手動 手動 自動
スレーブにDumpをインポート スレーブ 手動 手動 自動
レプリケーション設定 スレーブ 手動
(change master toコマンド)
手動
(ストアドプロシージャ提供)
自動

データインレプリケーション

表を見ればわかるように
データインレプリケーションはほとんどMySQL(OSS)と同じ手順になります。
最後のスレーブからマスタに向ける設定をchange master toコマンドではなくAzureが提供するストアドプロシージャで実現します。
これがなぜかというとAzure Database for MySQLではchange master toコマンドを打つと権限エラーとなります。

ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or REPLICATION_SLAVE_ADMIN privilege(s) for this operation

これはMySQLではchange master toコマンドを打つためにはREPLICATION_SLAVE_ADMINという権限が必要なのですが、
Azure Database for MySQLで利用者側に提供されるユーザにはこの権限が付与されていないことが原因です。
https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_replication-slave-admin

ではなぜAzureのストアドを実行するとレプリケーションできるかというと、このストアドがazure_superuserというSUPER権限を持ったユーザで作られているからです。
そのためMySQL(OSS)の手順の中でこのレプリケーション設定のところだけAzureのストアドを使用する必要があります。

読取レプリカ

逆に読取レプリカはこれぞPaaSの機能、というくらい全てを自動でやってくれます。
ただしこれはマスタと同じバージョンのMySQLのPaaSをスレーブとして作成しレプリケーションしてくれるものなので、今回MySQL5.7からMySQL8.0への移行の手段には使えません。

実をいうとデータインレプリケーションも異なるバージョン間のレプリケーションはサポートしていません。
ただしMySQL(OSS)のレプリケーションでは異なるバージョン間のレプリケーションを1世代だけサポートしています。
実際にAzureのストアドの中身を見てもほぼほぼchange master toしてるだけでMySQL(OSS)と同じことをしているので、
まぁ大丈夫だろうということでお客様にリスクを共有したうえで採用しました。

さて、データインレプリケーションを利用して検証を進める中で、様々な壁にぶつかりました。

レプリケーションフィルタが使えない

MySQL(OSS)のレプリケーションではフィルタ機能を使うことで必要なテーブルのみを同期することができます。
ただしAzure Database for MySQLではこのフィルタを作成する権限がないためにDB丸ごと同期する必要があります。
そのため移行対象外となるテーブルのデータは事前にDumpしておき、レプリケーション完了後にテーブルをTruncateしDumpからデータを戻す、という手順にしました。

マスタ側のファイアウォールで最低限のアクセスに絞れない

スレーブからマスタにbinlog要求するためにマスタでスレーブからのアクセスを許可する必要があります。
スレーブがMySQL on VMであればそのグローバルIPアドレスをマスタのファイアウォールで個別に許可できます。
しかしスレーブがPaaSの場合ははそうはいきません。
これはよくハマるAzurePaaSあるあるなので別途記事にする予定ですが、AzureのPaaSはグローバルIPアドレスを固定化してくれません。
そのためマスタとなるAzure Database for MySQLのファイアウォーrうで「Azure サービスへのアクセスを許可」にチェックを入れる必要があります。
これはAzureのデータセンタが持つグローバルIPアドレス全てを指しているため、VMを含むAzure上の全リソースからアクセス可能となります。
認証情報を持った悪意ある内部犯に限定されるものの、データ流出の懸念があります。

今回お客様は仕様上仕方ない、と許容してくれましたが、お客様によっては許容してもらえないこともあるかと思います。

構築した時期でバイナリログのデフォルト有効/無効の仕様が違う

我々が検証を開始したのは2020年4月頃で、Azure Database for MySQL(General Purpose)はリソースを作成するとバイナリログの出力設定はデフォルトで有効となっていました。
しかし実際にお客様の環境で検証をしてみたところ、マスタとなるAzure Database for MySQLのバイナリログは無効となっていました。
MSサポートに問い合わせたところ、リソースを作成した時期により仕様が変わったとのことでした。
具体的にはディスクの4TBが上限だった時点までにデプロイした Azure Database for MySQL については、バイナリログがデフォルトで無効となっているそうです。
過去のAzure Database for MySQLのGAを調べたところ以下がヒットしました。
2019/11/11に4TBの壁が解消されたようなので、これ以降に作成されたリソースはバイナリログがデフォルトで有効になっていると思われます。

Azure Database for MySQL:読み取りレプリカの一般提供開始

https://azure.microsoft.com/ja-jp/updates/azure-database-for-mysql-read-replica-now-generally-available/
更新: 2月 27, 2019
Azure Database for MySQL では、1 つの Azure Database for MySQL サーバー (マスター) のデータを同じリージョン内の最大 5 つの Azure Database for MySQL サーバー (レプリカ) に非同期で連続的にレプリケートできるようになりました。

General availability: Azure Database for MySQL 4-TB server storage

https://azure.microsoft.com/ja-jp/updates/general-availability-mysql-4-tb-server-storage/
更新: 6月 28, 2018

Azure Database for MySQL の大容量のプレビュー開始

https://azure.microsoft.com/ja-jp/updates/mysql-large-storage-generally-available/
更新: 11月 11, 2019
Azure Database for MySQL サービスで、最大 16 TB のストレージと最大 20,000 IOPS がサポートされるようになりました。

最後に

今回Azure Database for MySQLでレプリケーションをした際にハマったことについてまとめました。
パッと思いついたことだけ羅列したので、また思い出したら追記します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ラズパイにDjangoの環境を構築(MySQL)

ラズパイにdjango環境を構築します。したくなったので。
使用したラズパイは Raspberry pi 3B+ 。

Django環境の構築情報が調べると古いものばかりなのと、ラズパイにはMySQLが入らないのでmariadbで設定する際に苦戦したのでメモです。

バージョン確認

$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description: Raspbian GNU/Linux 9.11 (stretch)
Release: 9
Codename: stretch
$ uname -a
Linux raspberry 4.19.66-v7+ #1253 SMP Thu Aug 15 11:49:46 BST 2019 armv71 GNU/Linux

アップデート

$ sudo apt update
$ sudo apt upgrade -y
$ sudo reboot

Python

最初からインストールされてるはずなので飛ばしていいです。
バージョンが低い場合は3.7.xまでアップデートした方がいいかも。

$ sudo apt install python3 python3-dev
$ python3 -V
Python 3.7.3

Django

本体をインストール

$ sudo apt install python3-django
$ pip3 install Django==3.0.6
$ django-admin --version
3.0.6

$ pip3 list --outdated で最新バージョンか確認できる。

MySQL(mariadb)

MySQL自体はインストールできないのでmariadbをインストールします。

本体をインストール

$ sudo apt install mariadb-server
$ mysql --version
mysql  Ver 15.1 Distrib 10.3.22-MariaDB, for debian-linux-gnu (i686) using readline 5.2

クライアントをインストール

$ sudo apt install libmariadb-dev
$ pip3 install --no-binary :all: mysqlclient
~ 
Successfully installed mysqlclient-1.4.6

初期設定

rootユーザーのパスワードを設定する。
'********'を任意のパスワードにする。

$ sudo -i
# mysql -u root
mysql> use mysql;
mysql> update user set plugin='' where user='root';
mysql> update mysql.user set password=password('********') where user='root';
mysql> flush privileges;

select user,password,plugin from user; で設定情報を確認できる。
vlcsnap-2020-05-27-16h16m34s284.png

DBを作成

mysql> create database mydb;

プロジェクトを作成して起動

Djangoプロジェクトを作成

$ django-admin startproject mysite

設定を変更

settings.pyの以下の2点を変更する。

$ sudo nano mysite/mysite/settings.py

ALLOWED_HOSTS = []の[]に'*'を入力する。

settings.py
# ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['*']

初期ではsqlite3を指定しているんでコメントアウト(または削除)し、MySQLの設定を記述する。
'********'を設定したパスワードにする。

settings.py
DATABASES = {
#    'default': {
#        'ENGINE': 'django.db.backends.sqlite3',
#        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#    }
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydb',
        'USER': 'root',
        'PASSWORD': '********',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

設定が正しく行えたか確認する

$ python3 mysite/manage.py migrate

vlcsnap-2020-05-27-16h15m56s570.png

問題がなければ起動

$ python3 mysite/manage.py runserver

起動したらブラウザで確認しよう。
ローカルの8000番ポートで接続できる。
http://127.0.0.1:8000

これで土台ができたのであとは参考サイトを見ながらアプリを作成できます。

image.png

お疲れさまでした。

トラブルシューティング

mysqlclientをインストールできない

Error Code 1とか以下の様な文言が出てインストールできない。

OSError: mysql_config not found

以下をインストールすること。

$ sudo apt install python3-dev libmariadb-dev

MySQLにrootユーザーで入れない。

rootユーザーのパスワードを忘れた場合、パスワードを再設定。

$ mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

パスワード再設定

MySQLをセーフモードで起動

$ sudo -i
# service mysqld stop
# mysqld_safe --skip-grant-tables &

rootユーザーのパスワードを設定

# mysql -u root
mysql> use mysql;
mysql> update user set plugin='' where user='root';
mysql> update mysql.user set password=password('********') where user = 'root';
mysql> flush privileges;

セーフモードで起動したMySQLを終了する

# kill -KILL [mysqld_safe のPID]
# kill -KILL [mysqld のPID]

※mysqldのPIDの調べ方

$ ps aux | grep mysqld

MySQLを起動させる

# service mysqld start

権限を再設定

※権限で怒られてなかったらやらなくていいです。コマンドの内容を理解して行ってください。
userテーブルを全削除してrootユーザーに全権限を付与してみます。

mysql> use mysql;
mysql> select * from user;
mysql> truncate table user;
mysql> flush privileges;
mysql> grant all privileges on *.* to root@localhost identified by '********' with grant option;
mysql> flush privileges;

セーフモードで起動しない場合

# mysqld_safe --skip-grant-tables &
$ 2018-08-05T15:34:57.6NZ mysqld_safe A mysqld process already exists

既に起動していると言われて怒られたら既に動いているプロセスを止めましょう。
上記にあるPIDを確認してKILLすること。

MySQLクライアントが無いと怒られる時

古い情報を見ながらやってると起きがちなやつ。

Error loading MySQLdb module: No module named 'MySQLdb'.
Did you install mysqlclient or MySQL-python?

以前のバージョンでの解決策として $ pip install mysqlclient とかやったりsetting.pyに以下のようなプログラムを書くようで、エラーをそのまま調べるとこの情報ばかりでてくるけど、この解決策自体が古い。

settings.py
# この解決策は古いので削除してください
import pymysql
pymysql.install_as_MySQLdb()

django2.0からはpymysqlは非推奨となっているので、もしインストールしているならアンインストールしてください。
現在はmysqlclientを使うので、以下の内容でインストールしてください。

$ pip3 install --force-reinstall --ignore-installed --no-binary :all: mysqlclient

よく分かってませんが、普通にインストール( $ pip3 install mysqlclient )するだけではdjangoは参照してくれない様で同様のエラーになります。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【備忘録】MySQLで文字化け(RDS)

テーブルの日本語が文字化けしてしまう

image.png

原因はRDSにあります。
RDSのパラメーターグループでDBで利用するキャラクターセットを設定しているようです。
-character_set_client
-character_set_connection
-character_set_database
-character_set_results
-character_set_server

しかし、既にDBに設定されたパラメーターグループはAWSからは変更できないようです。
なので以下の方法で変更する!

まずDBに設定されているパラメーターの確認

show variables like 'character_set%';

「character_set_database」には「latin1」が使用されています。
これを「utf8」に変更する必要があります。
image.png

テーブルに設定されているキャラクターセットの確認

すでに作成されているテーブルにもキャラクターセットの設定が行われているようです。
以下のコマンドで確認しましょう。

show create table テーブル名;

「latin1」が使用されているみたいですね。
image.png

キャラクターセットの設定変更

以下のコマンドを実行してください。

ALTER DATABASE totsuka_dev default character set utf8;

再度確認すると変更されていることが分かると思います。
image.png

しかし、これ以降できるテーブルに対してこのキャラクターセットが適応されるので、
既存のテーブルのキャラクターセットは「latin1」のままです。。
image.png
なので、テーブルを再作成しましょう!

DBソフトには基本既存のテーブルを作成するためのSQL文をエクスポートできる機能があるので、それを利用しましょう!
(※コピーだとキャラクターセットの内容もコピーしてしまうので、一から作成する必要があります。)
今回はphpMyAdminを使用します。
対象のテーブルを選択し、「エクスポート」タブをクリックしてください。
image.png

出力をテキストで表示します。
image.png

今回は「構造」だけあればOKだったので、「構造」を選択します。
既存データも欲しければ「構造とデータ」を選択してください。
ちなみに、「構造はCreate文」、「データはInsert文」でエクスポートしてくれます!
image.png

あとは実行ボタンをクリックするだけ!
image.png

画面に以下のようにテキストで表示されます!
image.png

そしてこれを修正します。

-- テーブルの構造 `videos_search`--

CREATE TABLE IF NOT EXISTS `videos_search` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `videoId` varchar(20) DEFAULT NULL,
  `channelId` varchar(30) DEFAULT NULL,
  `title` varchar(250) DEFAULT NULL,
  `description` varchar(250) DEFAULT NULL,
  `publishedAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

①既存のテーブル名と名前が同じなので、仮の名前を付けてあげましょう。
②また、最後の行の以下の箇所は削除しましょう。既にデフォルトで「CHARSET」に「utf8」を設定するようになっているはずなので大丈夫です。
「DEFAULT CHARSET=latin1 AUTO_INCREMENT=6」

-- テーブルの構造 `videos_search`--

CREATE TABLE IF NOT EXISTS `videos_search2` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `videoId` varchar(20) DEFAULT NULL,
  `channelId` varchar(30) DEFAULT NULL,
  `title` varchar(250) DEFAULT NULL,
  `description` varchar(250) DEFAULT NULL,
  `publishedAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

このCreate文を実行してみましょう!
image.png

作成したテーブルを確認してみましょう。確認方法はいろいろありますが、
今回はエクスポートの画面から確認してみます。
image.png

「CHARSET=utf8」になっていますね!
あとは既存のテーブルを削除し、新たに作成したテーブル名を既存のテーブル名に変更すればOKです!

以上、お疲れ様でした!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向けハンズオン】WindowsにDockerでPHP/MySQL/Apache環境構築(第2回:PHP動かすところまで)

概要

 前回の記事はこちら:

 新人もベテランも本当にエンジニアによくある、「開発環境建てるのめんどくさい問題」を解決する糸口を模索していました。そこで行き当たったWindows環境でDockerを使って開発出来るようにする、という着地に対してアプローチしていくハンズオンです。
 1回1時間程度の作業時間でやるルールにして、記事は細切れに書いて行くスタイル。あと参考にさせていただいた記事はこちらです。
 ※https://qiita.com/hirosnow/items/cbe2a90ba1c6921fea1a

目標

  • PHP/MySQL/Apacheで古き良きWEBアプリケーションの開発環境を作る
  • つくった開発環境を他の人に配布できるようにする
  • ↑の「配布された人が簡単に開発環境を作れる手順をまとめる」ところまでがゴール

では行ってみましょう。

本日の作業内容

作業ディレクトリの作成

参考にした記事に従って、「C:\Users\あなたのPCのユーザー名\home」というディレクトリを作成しました。
※参考との相違点①:「\work」になっているところを「\home」い変えました(好み)

home/
 ├ html/
 │ └ index.php
 ├ mysql/
 ├ php/
 │ └ php.ini
 └ docker-compose.yml

設置したファイルの記述

ちなみにここに来て大変今更ですが「Dockerってなんや」「Dockerfile?docker-compose.yml?」あたりでそもそも理解に躓いたタイミングがあり、その解消になったyoutube動画を転載させていただきます。
https://www.youtube.com/watch?v=VIzLh4BgKck

記述したdocker-compose.yml

version: '3'

services:
  php:
    image: php:7.2-apache
    volumes:
      - ./php/php.ini:/usr/local/etc/php/php.ini
      - ./html:/var/www/html
    ports:
      - 32778:80
  mysql:
    image: mysql:5.7
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test
      MYSQL_USER: test
      MYSQL_PASSWORD: test
    command: --innodb-use-native-aio=0
    ports:
      - "32780:3306"
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      PMA_ARBITRARY: 1
      PMA_HOST: mysql
      PMA_USER: test
      PMA_PASSWORD: test
    restart: always
    links:
      - mysql:mysql
    ports:
      - '32779:80'

記述したphp.ini(ホントはxamppでもともと使ってたやつを入れたんですが、恥ずかしいのでこちらの記述で)

[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

記述したindex.php(ここは別になんでもいいと思う)

<?php
    phpinfo();

いざ、起動

該当フォルダに移動

cd (docekr-compose.ymlのあるディレクトリ)

いざ、起動

docker-compose up -d

接続してみる

http://127.0.0.1:32778/」

おお、すごい。来てる。簡単。
image.png

終わり。

コマンド一発は超絶楽ですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向けハンズオン】WindowsにDockerでPHP/MySQL/Apache環境構築(第1回:DockerDesktopを入れるまで)

概要

 新人もベテランも本当にエンジニアによくある、「開発環境建てるのめんどくさい問題」を解決する糸口を模索していました。何しろ、自分と共通の開発環境つくってもらうのがめんどくさくて仕方がない。
 で、そういった課題への解決策としては当然のように「Docker」が提唱されることになるわけです。
「でも自分の開発環境Windowsなんだよなあ」
 とはいえ行けるかどうか半信半疑で調べてみたら、結構参考記事が上がっていたので「よしじゃあこれも備忘つけながらやってみるか」と思い立った次第です。

 同じく例によって、1回1時間程度の作業時間でやるルールにして、記事は細切れに書いて行くスタイル。長くなると読む側もダレるかなあと思ったというのもあります。

目標

  • PHP/MySQL/Apacheで古き良きWEBアプリケーションの開発環境を作る
  • つくった開発環境を他の人に配布できるようにする
  • ↑の「配布された人が簡単に開発環境を作れる手順をまとめる」ところまでがゴール

では行ってみましょう。

作業内容

dockerインストール

こちらからインストール → https://docs.docker.com/docker-for-windows/install/

その後ダウンロードしたexeファイルを使ってインストール。

image.png

↓↓↓

image.png

↓↓↓

無事完了
image.png

まさかのエラー(でなければスルー)

意気揚々とインストールしたdockerを始めようとしたらいきなりエラーで出鼻をくじかれる。なぜ。。。
image.png

調べたらこんな記事が出てきました。
https://qiita.com/toro_ponz/items/d75706a3039f00ba1205

手順通りやったらできました。良かった。PCの管理者、ユーザーの利用者で躓くかもしれない。
image.png

初期セットアップ

とりあえず指示通り青いボタンを押しながら「Start」「Next Step」
image.png

(色々出る)
image.png

Docker Hubのアカウントが必要でした。
僕はたまたまもってましたが、ここで取得しましょう。
https://hub.docker.com/
image.png

で、Sign inしておしまいです。チュートリアルとか色々出るけど最後はこの画面でした。
image.png

終わり。

なんだかんだ読みながらやるとインストールだけで1時間とか立ちますよね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【MySQL】CSVからサクッとインポートしたかったけどハマった件

何をしたかったの?

いまのお仕事のテスト用に、DBに値をサクッと登録したかった。

そのために使えるCSV生成→DB登録機能は既に実装されていたが、
テスト環境でやっててもそのファイルを使ったらお客さんに通知が飛ぶし、
かといって、通知する部分をコメントアウトしたりってのも少し手間…

なんて思って、【やったことなかったけど】CSVから直接インポートしちゃえばよくね???
という軽い気持ちで試したら存外ハマったので、備忘録としてまとめていく。

この記事で紹介すること

MySQLに、CLIからコマンド打ってCSVをインポートする方法。
ハマったところから紹介するので、答えだけ知りたい方は、最後の章だけ見てもらえれば。

紹介していく。

まず手元にCSVを用意する。

そして、MySQLにログインし、インポート先のDBを選択。
以下のコマンドを打つ。

MySQL
$ load data local infile "/Users/[userName]/Import.csv" \
into table [tableName] \
fields terminated by ',' \
optionally enclosed by '"';

ちなみに、
terminatedは区切り文字、
optionally enclosedは囲い文字
となっているので、環境次第で変える必要がある。

実行結果は…

実行結果
ERROR 1148 (42000): The used command is not allowed with this MySQL version

ググった結果、local_infileの設定が変なのではないか?とのことなので、
以下のコマンドを実行。(同じくMySQL内)

MySQL
mysql> SELECT @@local_infile;
実行結果
+----------------+
| @@local_infile |
+----------------+
|              1 |
+----------------+
1 row in set (0.00 sec)

このファイルの値が、先程のコマンドの権限?的なところを担っているらしいのだが、
僕はそもそも1だった。

ここが0の場合は、1に変えて再実行してみるのが良いかも。
それでもダメだったら、以下のコマンドを試してみると良いかも。

ではどうするか

MySQLにログインする際に、--local_infile=1を指定する。

$ mysql -u $userName -p -h $IP -P $port --local_infile=1

これでMySQLのログインパスワードを入力し、MySQLにログインできたら、
インポート先のデータベースを選択し、先程のコマンドをもう一度ためす。

MySQL
$ load data local infile "/Users/[userName]/Import.csv" \
into table [tableName] \
fields terminated by ',' \
optionally enclosed by '"';
実行結果
Query OK, 216 rows affected, 216 warnings (0.01 sec)
Records: 216  Deleted: 0  Skipped: 0  Warnings: 216

なんかやたらWarnings出てますが、phpMyAdminで値を確認したところ、
問題なく登録されていた。

(ただ、自分の場合、CSVにID列がなくて、わざわざCSVにID列を作らないとうまいこと登録できてません。。。)
(数十行程度なのでまぁ良いかと自分でID列しこしこ作ったんですが、ここも楽する手段が知りたいです。。。)

こんなしょっぱい経験が、どなたかの役に立つことがもしあれば嬉しいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Deno+MySQL+DockerでAPIサーバーをさくっと作る

Deno

TypeScriptを標準サポートしているDenoのv1.0がリリースされたということで興味があったので触ってみました。
あと恐竜がかわいい。

作るもの

deno + MySQL + docker-composeでローカル環境にシンプルなAPIサーバーです。
適当にどう森の村民を登録して編集するようなやつとします。

全体がみたい方はこちら

https://github.com/rydein/deno_first_api

インストールとか下準備

公式に書いてある通りですが以下のコマンドを流すだけです

$ brew install deno

エディタはVSCodeを使いますがdenoのimport記法に対応させるためこちらのプラグインを追加しましょう。

Screen Shot 2020-05-25 at 23.49.31.png

Docker + docker-compose

deno用のDockerfileとdocker-compose.ymlはこちらを使います

Dockerfile
FROM hayd/ubuntu-deno:1.0.0

EXPOSE 3000

WORKDIR /app

USER deno

ADD . .

RUN deno cache index.ts

CMD ["run", "--allow-net", "index.ts"]
docker-compose.yml
version: '3'

services:
  deno:
    build: .
    ports:
      - "3000:3000"

  db:
    image: mysql:8
    ports:
        - "3306:3306"    
    environment:
      - MYSQL_ROOT_PASSWORD=Passw0rd
      - MYSQL_DATABASE=deno-dev
    volumes:
      - db-volume:/var/lib/mysql
      - ./mysql/conf:/etc/mysql/conf.d

volumes:
  db-volume:

ローカル環境立ち上げ

とりあえずMySQLをたちあげておきたいので動く環境だけ用意します

index.ts
import { Application, Router } from "https://deno.land/x/denotrain@v0.5.0/mod.ts";

const app = new Application();
const router = new Router();

app.get("/", (ctx) => {
  return {"hello": "world"};
});
await app.run();

立ち上げます

$ docker-compose build
$ docker-compose up -d

DB migration

まずはDBのテーブル定義を作成していきます。
migrationにはこちらのツールを使います。

https://deno.land/x/nessie

init

# nessie.config.ts を作成してdb接続情報を追記する
$ deno run --allow-net --allow-read --allow-write https://deno.land/x/nessie/cli.ts init

MySQL以外のデフォルトコードが生成されますが今回は不要なので消してしまいましょう。
configMySqlにDB接続情報を追記します。

nessie.config.ts
const configMySql = {
  migrationFolder: `./migrations`,
  connection: {
    hostname: "localhost", // hostからDockerのMySQLコンテナに繋ぐ
    port: 3306,
    username: "root",
    password: "Passw0rd",
    db: "deno-dev",
  },
  dialect: "mysql",
};

export default configMySql;

接続情報が作成できたのでmigrationファイルを作成します。
create_villagersの部分は作成するテーブルによって適宜読み替えてください。

# 村民のmigration
$ deno run --allow-net --allow-read --allow-write https://deno.land/x/nessie/cli.ts make create_villagers

migration/ディレクトリにmigrationファイルが生成されるので必要な情報を追記していきます。
村民には名前、性別、性格、誕生日があるので追加します。

migrations/1590336600981-create_villagers.ts
import { Schema } from "https://deno.land/x/nessie/mod.ts";

// migration ファイルにテーブル情報を追加する
export const up = (schema: Schema): void => {
    schema.create("villagers", (table) => {
        table.id();
        table.string("name", 100).nullable();        // 名前
        table.string("gender", 100).nullable();      // 性別
        table.string("personality", 100).nullable(); // 性格
        table.string("birthday", 100).nullable();    // 誕生日
    });
};

export const down = (schema: Schema): void => {
    schema.drop("villagers");
};

migrationを実行しましょう。

#migration の実行
$ deno run --allow-net --allow-read https://deno.land/x/nessie/cli.ts migrate

Query Builder

DBからデータを参照したり登録したりするにはこちらのクエリビルダーを使います。

https://deno.land/x/dex

場所はどこでも良いですがmodels/villagers.tsにDBに登録、取得する処理を作成します。

models/villagers.ts
import Dex from "https://deno.land/x/dex/mod.ts";
import client from "./config.ts";

let dex = Dex({client: "mysql"});
let table = "villagers";

interface Villager {
    id?: number,
    name: string,
    gender: string,
    personality: string,
    birthday: string
}

///
/// 新しい村民を追加して追加したデータを返す
///
function addVillager(villager: Villager) {
    const insertQuery = dex.queryBuilder().insert([villager]).into(table).toString();
    return client.execute(insertQuery).then((result: any) => {
        const getQuery = dex.queryBuilder().select().from(table).where({id: result.lastInsertId}).toString();
        return client.execute(getQuery).then((result: any) => result.rows ? result.rows[0] : {});
    })
}

///
/// 全ての村民を返す
///
function getAllVillagers() {
    const getQuery = dex.queryBuilder().select("*").from(table).toString();
    return client.execute(getQuery);
}

///
/// 村民の更新を行う、更新されたデータを返す
///
function editVillager(id: number, villager: Villager) {
    const editQuery = dex.queryBuilder().from(table).update(villager).where({id}).toString();
    return client.execute(editQuery).then(() => {
        const getQuery = dex.queryBuilder.select().from(table).where({id}).toString();
        return client.execute(getQuery).then((result: any) => result.rows ? result.rows[0] : {});
    });
}

///
/// 村民の削除
///
function deleteVillager(id: number) {
    const deleteQuery = dex.queryBuilder().from(table).delete().where({id}).toString();
    return client.execute(deleteQuery)
}

export {
    addVillager,
    getAllVillagers,
    editVillager,
    deleteVillager
}

Http Server

https://deno.land/x/denotrain

controllers/villagers.ts にコントローラーを作成し、APIのルーティングを作成してリクエストを処理していきます。

controllers/villagers.ts
import { Router } from "https://deno.land/x/denotrain@v0.4.4/mod.ts";
import { addVillager, getAllVillagers, editVillager, deleteVillager } from "../models/villagers.ts";

const api = new Router();

api.get("/", (ctx) => {
    return getAllVillagers().then((result: any) => {
        return result.rows;
    })
})

api.post("/", (ctx) => {
    const body = {
        name: ctx.req.body.make,
        gender: ctx.req.body.gender,
        personality: ctx.req.body.personality,
        birthday: ctx.req.body.birthday,
    }

    return addVillager(body).then((villager: any) => {
        ctx.res.setStatus(201);
        return villager;
    })
})

api.patch("/:id", (ctx) => {
    const body = {
        name: ctx.req.body.make,
        gender: ctx.req.body.gender,
        personality: ctx.req.body.personality,
        birthday: ctx.req.body.birthday,
    }

    return editVillager(ctx.req.params.id as number, body).then((result: any) => {
        return result;
    })
});

api.delete("/:id", ctx => {
    return deleteVillager(ctx.req.params.id as number).then(() => {
        ctx.res.setStatus(204);
        return true;
    })
});

export default api;

index.tsにサーバーのエントリーポイントを用意し、作成したRouterとURLをセットします。
/api/villagersに作成したRouterをセットすることで、このURL配下に上記で作成したルーティングが用意されます。

import { Application, Router } from "https://deno.land/x/denotrain@v0.4.4/mod.ts";
import api from "./controllers/villagers.ts";

const app = new Application({});
app.use("/api/villagers", api);

app.run();

起動

サーバーの用意ができたので起動しましょう、以下のURLでAPIが起動しているはずです。
http://localhost:3000/

$ docker-compose build
$ docker-compose up -d

まずは最初のAPIを作ってみましたが、ライブラリを探すのも公式ページから検索できてドキュメントも読みやすくそろっているのでとくにハマることなく進みました。

Dockerのイメージも40MBぐらいで小さいので良さそうですね、次はクラウド環境にデプロイしてみたいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む