20200324のMySQLに関する記事は8件です。

【MySQL】SQLで基本統計量を求める

はじめに

基本統計量の算出は、ExcelやSPSSのようなツールや、あるいはRのような言語を使って求めることが多いと思います。
そのため、DB内のデータについて基本統計量を求める場合、一旦DBからデータを抽出してエクスポートするような形になるケースが多いのではないかと思います。

SQLには加減乗除の計算だけでなく、SUMAVGなどの集計関数も揃っているので、今回はSQLを使って基本統計量を求める方法を探ってみました。

使用した環境

  • OS
    • CentOS7.7(1908)
  • RDBMS
    • MySQL8.0.19

テストデータ

  • テストデータとして、Wikipediaに掲載されている八ヶ岳の標高データを利用しました。

テーブル

CREATE文
-- 山情報テーブルの作成。
CREATE TABLE `nkojima`.`mountain` (
  `id` INT AUTO_INCREMENT comment '山ID',
  `name` VARCHAR(50) NOT NULL comment '山名', 
  `altitude` double NOT NULL comment '標高',
  `note` VARCHAR(200) comment '備考',
  PRIMARY KEY (id),
  INDEX name_idx(name)
)
ENGINE = InnoDB,
default charset=utf8mb4
comment='山情報';

データ

INSERT文
INSERT INTO mountain
  (name, altitude, note)
VALUES
  ('編笠山',2524,'南八ヶ岳'),
  ('西岳',2398,'南八ヶ岳'),
  ('三ッ頭',2580,'南八ヶ岳'),
  ('権現岳',2715,'南八ヶ岳'),
  ('赤岳',2899,'南八ヶ岳'),
  ('中岳',2700,'南八ヶ岳'),
  ('阿弥陀岳',2805,'南八ヶ岳'),
  ('横岳',2829,'南八ヶ岳'),
  ('硫黄岳',2760,'南八ヶ岳'),
  ('赤岩の頭',2656,'南八ヶ岳'),
  ('峰の松目',2567,'南八ヶ岳'),
  ('箕冠山',2590,'北八ヶ岳'),
  ('根石岳',2603,'北八ヶ岳'),
  ('天狗岳',2646,'北八ヶ岳'),
  ('中山',2496,'北八ヶ岳'),
  ('丸山',2330,'北八ヶ岳'),
  ('茶臼山',2384,'北八ヶ岳'),
  ('縞枯山',2403,'北八ヶ岳'),
  ('北横岳',2480,'北八ヶ岳'),
  ('大岳',2381,'北八ヶ岳'),
  ('双子山',2224,'北八ヶ岳'),
  ('蓼科山',2530,'北八ヶ岳'),
  ('八子ヶ峰',1833,'北八ヶ岳');

基本統計量の算出

平均値、最小値、最大値

  • 平均値、最小値、最大値は、それぞれAVGMAXMINという初歩的な関数を使って簡単に求められます。
平均値、最小値、最大値を求めるSQL
SELECT
  AVG(altitude) AS 平均値,
  MAX(altitude) AS 最大値,
  MIN(altitude) AS 最小値
FROM
  mountain;
実行結果
+-------------------+-----------+-----------+
| 平均値            | 最大値    | 最小値    |
+-------------------+-----------+-----------+
| 2536.217391304348 |      2899 |      1833 |
+-------------------+-----------+-----------+

中央値

  • 以下のSQLは、mysqlで中央値(メジアン)を出す方法に記載されていた方法を、少しだけ改変した方法となります。
    • データの個数が偶数の時にも対応しています。
  • 幾つものSQLに分かれて複雑化している原因は、LIMIT句やOFFSET句に変数を設定できないというMySQLの仕様によるところが大きいです。
中央値を求めるSQL
-- 1. データの個数を求める。
SELECT COUNT(*) INTO @row_count FROM mountain;

-- 2. offset値とlimit値を取得する。
-- データの個数が奇数の時:中央値は「昇順に並べた際の順位が中央となる値」とする。
-- データの個数が偶数の時:中央値は「中央の前後のレコードの件数の平均値」とする。
SET @offset = 0;
SET @limit = 0;
SELECT 
  CASE WHEN @row_count % 2 = 0 THEN
    FLOOR( @row_count / 2 ) - 1
  ELSE
    FLOOR( @row_count / 2 )
  END INTO @offset
FROM dual;

SELECT 
  CASE WHEN @row_count % 2 = 0 THEN
    2
  ELSE
    1
  END INTO @limit
FROM dual;

-- 3. PreparedStatementにオフセット値をバインドして実行する。
PREPARE
  pstmt_median
FROM
  'SELECT
     AVG(temp.altitude) AS 中央値
   FROM
     (select altitude from mountain order by altitude asc limit ? offset ?) AS temp';
EXECUTE pstmt_median USING @limit, @offset;
実行結果
+-----------+
| 中央値    |
+-----------+
|      2567 |
+-----------+

分散

  • 分散は「『平均値からの差の2乗』の総和をデータ数で割ったもの」です。
  • 1つのSQLでまとめるのが厄介そうでしたが、インラインビュー(FROM句内での副問い合わせ)を使ったら1つのSQLにまとめられました。
分散を求めるSQL
-- 1. インラインビューで平均値を求める。
-- 2. 「平均値からの差の2乗」の平均値で分散を求める。
SELECT
  AVG(
    POW(T1.altitude-T2.avg_alt, 2)
  ) AS 分散
FROM
  mountain T1,
  (
    SELECT
      AVG(altitude) AS avg_alt
    FROM
      mountain
  ) AS T2;
実行結果
+------------------+
| 分散             |
+------------------+
| 50376.5179584121 |
+------------------+

標準偏差

  • 標準偏差は「分散の平方根」なので、「分散」のSQLをベースにして作りました。
標準偏差を求めるSQL
-- 1. インラインビューで平均値を求める。
-- 2. 「平均値からの差の2乗」の平均値で分散を求める。
SELECT
  AVG(
    POW(T1.altitude-T2.avg_alt, 2)
  ) AS 分散
INTO
  @variance
FROM
  mountain T1,
  (
    SELECT
      AVG(altitude) AS avg_alt
    FROM
      mountain
  ) AS T2;

-- 3. 分散の平方根を求める。
SELECT SQRT(@variance) AS 標準偏差;
実行結果
+-------------------+
| 標準偏差          |
+-------------------+
| 224.4471384500415 |
+-------------------+
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【MySQL】PacketTooBigExceptionの回避方法

要約

  • MySQLに大きなデータをInsertしようとすると発生する例外“PacketTooBigException“の対応方法を紹介します。
  • 記事の後半はMySQL各バージョンの設定値と、関連記事を紹介します。

PacketTooBigExceptionの発生

MySQLの設定“max_allowed_packet“の設定値を超えた容量のデータをInsertしようとすると発生します。BLOB形式でデータ突っ込むときによく見ますね。

Caused by: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (6395830 > 4194304).
You can change this value on the server by setting the max_allowed_packet' variable.

対応方法

1. 設定値の確認

まずは現在の設定値から確認して行きましょう。
mysqlコマンドでMySQLに接続します。

mysql -u {ユーザ名} -p -h {ホスト名} -P {ポート番号}

MySQLにログイン後、以下のコマンドを実行します。

mysql> show variables like 'max_allowed_packet';

現在の’max_allowed_packet’の設定値が表示されます。

+————————————————————+——————————+
| Variable_name      | Value    |
+————————————————————+——————————+
| max_allowed_packet | 4194304  |
+————————————————————+——————————+
1 row in set (0.01 sec)

Valueの単位はbyteです。つまり上記は4194304byteですので、4MBですね(4 * 1024 * 1024)。

さて、お次は’max_allowed_packet’の設定値を変更していきましょう。

2. MySQLへの設定

ここではコマンドラインでの設定と、設定ファイルmy.cnfを使った設定方法を説明します。

コマンドラインでの設定

SET文を使って設定します。
MySQLにログインしたあと、以下のコマンドを実行しましょう。

# max_allowed_packetを40MBに設定する
mysql> set global max_allowed_packet = 40 * 1024 * 1024;

SET文での設定にはグローバル変数、セッション変数の2種類があります。グローバル変数に設定した値は以後接続した全クライアントに影響を与えます。対して、セッション変数は現在の接続中のみの設定です。

ここではmax_allowed_packetの設定を以後も反映させるため、グローバル変数で設定します。set globalとすることでグローバル変数での設定となります。

値には式を入れることもできますので、41943040(40MB)と入力するより、上記のように“40 * 1024 * 1024“としたほうが見やすくオススメです。

コマンドでの設定は以上です。
コマンドラインでの設定は手軽さが便利ですね。取り急ぎ確認のためだったり、実施が一度きりのときに使えます。

プロパティファイルmy.cnfでの設定

プロパティファイルに設定後、MySQLを再起動することによって設定を反映できます。mysql --helpと入力すると、コマンドの説明とともにmy.cnfの配置場所について記述されています。

Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf 

左から優先的に採用されるようですね。特になにも無ければ"/etc/my.cnf"でよいと思います。なければtouch /etc/my.cnfでa新規にファイルを作成しましょう。作成したファイルに、次のように記載します。

[mysqld]
max_allowed_packet=40MB

最後にMySQLを再起動して設定値を反映します。

mysql.server restart

プロパティファイルでの設定方法は以上です。
my.cnfは設定値をファイルで管理できるので、複数のサーバで使いまわせる点で便利ですね。

MySQLバージョン毎の“max_allowed_packet“デフォルト値

MySQLの各バージョンでデフォルト値が異なります。以下、リファレンスマニュアルからの抜粋です。

MySQL5.6

サーバーのデフォルトの max_allowed_packet 値は 1M バイトです。

引用元:MySQL :: MySQL 5.6 リファレンスマニュアル :: B.5.2.10 パケットが大きすぎます

MySQL5.7

The server’s default max_allowed_packet value is 4MB.

引用元:MySQL :: MySQL 5.7 Reference Manual :: B.4.2.9 Packet Too Large

MySQL8.0

The server’s default max_allowed_packet value is 64MB.

引用元:MySQL :: MySQL 8.0 Reference Manual :: B.4.2.9 Packet Too Large

関連記事

Qiita

StackOverflow

技術系ブログ

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

MySQL データを更新する度にcreated がupdateされちゃう件に関して

問題:
Created(timestamp型)順でデータを表示。
カラムを修正した時Createdの時間も更新されてしまい
最下位に表示されるはずの一番古いデータが
最上位に表示されてしまう。
→不本意...

原因:
mysqlのtimestamp型には、デフォルトで
「CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP」
がついてきてしまう。

解決:ALTER TABLE テーブル名 CHANGE created created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

*参考
https://blog.officekoma.co.jp/2016/11/mysql-timestamp.html

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

【Laravel】Docker for WindowsでLaradock(+MySQL)に挑戦(※格闘)してみた。【備忘録】

はじめに

Docker for WindowsでLaradockの環境構築をして、Webアプリが作れるところまで記載しております。

DBに関してはMySQLでphpmyadminも利用できるようにしています。

※まだできていませんが、PostgreSQLでの環境構築の格闘記録はこちらにあります。(なんでこんなに難しいの。。。)

https://chobimusic.com/laradock_postgresql/

※僕の備忘録でもあり、構築できるようになるまでにかなり苦労したのでとても長文です。かなりのエラーを潰してきたので、部分部分かいつまんで参考にしていただければと思います。どなたかの参考になれば幸いです。※

参考記事


Windows10でLaradockを使ってLaravel 5.5環境を作る
https://qiita.com/sket88/items/4de708ce394179c61d8a


DockerでMySQL複数バージョンを共存させる
https://qiita.com/tanakaworld/items/427b94ea0435b5dccfa2


LaradockのMySQLに接続できなくてはまった話
https://qiita.com/dnrsm/items/4bd078c17bb0d6888647


laradockの環境設定からMySQL接続まで
https://qiita.com/yknsmullan/items/dea4102cf14b1b66e5af


docker起動でportが確保できないエラーの解決
https://nijoen.net/blog/773/


Dockerでコンテナの停止・削除ができなくなった時の対処法
https://qiita.com/musatarosu/items/31d6293a93e75ca6073e


docker docker-compose コマンド
https://qiita.com/souichirou/items/6e701f6469822a641bdd

参考書籍

https://www.amazon.co.jp/PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF-Laravel-Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA-%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B35-5-LTS%E5%AF%BE%E5%BF%9C/dp/4802611846

環境構築


(Dockerのインストールは、書籍を参考にインストール)

フォルダ作成。

$ mkdir laravel_app 
$ cd laravel_app

git cloneコマンドでLaradockのダウンロード後、.envファイルの作成
$ git clone https://github.com/laradock/laradock.git
$ cd laradock
$ cp env-example .env

.envファイルを編集(※MySQLのバージョンが8.0以上になっているとセキュリティの関係でDockerがうまく動作しないらしい)
MYSQL_VERSION=5.7

APP_CODE_PATH_HOST=../laravel-practice/ //後でインストールするlaravelの名前

コンテナの初期化(実行コマンド※Dockerアプリは起動した状態※)
$ docker-compose up -d nginx mysql workspace phpmyadmin

ここでエラー発生。

どうやら3306ポートが使えないらしい。.envファイル上で3306と記載の部分を3307に変更して再度compose upするも同様のエラー。(追記:XAMPPを起動していたのを見落としていました。それが原因。)

XAMPPでも3307のポートを使用しているので、念のためその後ポートは3306に戻す。

ためしに以下のコマンドで起動してみる。

docker-compose up

バカみたいに時間がかかったのでctrl+cで離脱。
docker-compose up -d nginx mysql

上記と同様(3306ポートが使えない。)のエラーが発生。

一応下記のコマンドでstatusがupになっていれば起動しているらしい。

$ docker ps

どうやらnginx,php-fpm,workspace,docker:dindは起動してる。記載のないphpmyadminとmysqlが起動していない。

$ docker-compose exec --user=laradock workspace bash
laradock@0b80605539aa:/var/www$

ただnginxとworkspaceは起動しているのでとりあえずログインを試みたところログインはできた。
composer create-project laravel/laravel laravel-practice --prefer-dist "5.5.*"

さらにLaravelプロフェクトの作成を試みる。下記ディレクトリに作成されていることを確認。
(ここで最低限、Docker自体は起動していることは確認。MySQLのエラー解決に関しては後述。)

exitでコンテナからログアウト。.envファイル(laradock側の共有ディレクトリ)に以下を追記。

DB_HOST=mysql

サービスの終了
docker-compose stop

再起動
docker-compose up -d nginx mysql workspace phpmyadmin

やはり3306ポートエラーになる。

XAMPPを終了して3307に変更して再起動。(ここでXAMPPを切り忘れていたことに気付く。)

mysqlが起動した!!どうやらXAMPPと干渉しあってたっぽい。。。(3306はなんなんだ。。。)

Dockerを使う際はXAMPPを停止しましょう。

ただphpmyadminはエラーで起動できていないので、laravel-practiceの.envファイルを編集して再起動。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

⇓以下のように編集
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3307
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret

再起動してみてもphpmyadminのエラーは変わらず。

ダメもとでコンテナにログインしてmigrateしたところ下記のようなエラー。
そもそもartisanコマンドすら利かないことが判明。。。

$ docker-compose exec --user=laradock workspace bash
laradock@0b80605539aa:/var/www$ php artisan migrate
Could not open input file: artisan

localhostへアクセスしてもnot found。hostsファイルやらDockerの初期設定にも間違いがあるかもしれない。

戦いは続く…

再挑戦編


phpmyadminとの格闘


PCを再起動してからDockerを再起動してみる。

phpmyadminは変わらず起動しない。
※0.0.0.0:8080のバインドに失敗しました:ポートは既に割り当てられています

netstat -ano | find ":8080"
find: ‘:8080’: No such file or directory

このコマンドでポートで何が使用されているかわかるらしいが何も反応せず。。。
docker ps -a

調べると以前のプロセスもこのコマンドでチェックできるとのことで実行。

7 weeks agoとめちゃくちゃ怪しいログを発見。

docker rm docker ps -a -q

こちらで停止できるとのことだが
Error response from daemon: You cannot remove a running container
(デーモン(メモリ上の常駐ソフトウェア)からのエラー応答:実行中のコンテナを削除できません)

終了できそうなコマンドを一通り入力。

docker-compose kill
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

再起動するも変わらないので、まだ削除されていないコンテナがあるっぽい。。。
docker ps //起動中のコンテナを表示。
docker rm --force <コンテナID> //指定のコンテナを強制終了

見つけたコンテナを強制終了して再起動するもport被りの状況は変わらず。。。
docker-compose up -d

ためしに上記コマンド。(鬼時間かかる。。。おそらく3時間くらい待った。)長すぎるので割愛。最後の文が赤字の時点でアウト。。。

以下の通り何も表示されない。待った意味。。。一旦ステイ。。。

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

MySQLとの格闘


たまたまこんなものを見つける。(いつ入れたのか全く覚えていない。これが干渉している??)

見つけた。どうやらLaravelを学習する際に入れた模様。

一応MAMPインストールした過去があったのでこちらの共存も気になったが、起動してなければ特にコンフリクト(衝突)することはないそうなので追求せず。

とりあえずこいつを停止してみた。

おそらくこいつのせいでXAMPPのポートも3306で起動できず、3307に変更せざるを得なかったんだなと気づく。

とりあえず3306にDocker内のファイルを変更してみる。mysqlは3306でも起動するようになった!!

残る問題はphpmyadminとartisanコマンドの実行だ。。。

artisanコマンドとの格闘


laradock@48ebb9bcd534:/var/www$ php artisan serve
Could not open input file: artisan
$ cd laravel-practice
$ php artisan serve
Laravel development server started: <http://127.0.0.1:8000>

ディレクトリが違うだけだった。。。

が、http://127.0.0.1:8000にアクセスしてもエラー。

コンテナからexitしてもしやと思いコンテナに入らずにアクセス。

表示された。(これであってるのか。。。??) 追記:コンテナで環境構築してるのでartisan serveは不要なのを後に知る。

ためしにdockerを終了してからアクセスしたところ表示されないので合ってるっぽい。とりあえず構築成功??

マイグレートも失敗。これはテーブル作成などもしてないからなんとなく理解できる。

php artisan migrate

phpmyadminとの格闘②


docker-compose.ymlのphpmyadminのポート番号を8081に変更。
//ポートのみ変更した場合
phpmyadmin:
      build: ./phpmyadmin
      environment:
        - PMA_ARBITRARY=1
        - MYSQL_USER=root
        - MYSQL_PASSWORD=password
        - MYSQL_ROOT_PASSWORD=password
    ports:
    - 8081:80

//サーバ名を調べるのに試行錯誤したパターン。※ログインエラー。
mysql:
      build:
        context: ./mysql
        args:
          - MYSQL_VERSION=${MYSQL_VERSION}
      environment:
        - MYSQL_DATABASE=DB
        - MYSQL_HOST=DB
        - MYSQL_USER=root
        - MYSQL_PASSWORD=password
        - MYSQL_ROOT_PASSWORD=password
        - TZ=${WORKSPACE_TIMEZONE}

phpmyadmin:
      build: ./phpmyadmin
      environment:
        - PMA_ARBITRARY=1
        - PMA_HOST=mysql
        - PMA_USER=root
        - PMA_PASSWORD=password
      ports:
        - 8081:80

全てきれいにdoneになった。泣 (そして一体8080ポートは何に使用しているんだろうか。。。)

http://localhost:8081でphpmyadminへアクセス。

サーバ名。。。わからずログインできず。。。

(その後かなり格闘した末。。。)laravel-practiceの.envに従い入力したところログインに成功。
サーバ:mysql
ユーザー:default
パスワード:secret

以下参照

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3307
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret

喜びも束の間。データベースを作成する特権がありません。と表示。

.envファイルにこんな記載があるのを思い出す。ユーザーrootでパスワードrootを入力したところログイン。編集もできた◎

MYSQL_ROOT_PASSWORD=root

mysql -u root -p root //こちらからもアクセス可能

create database default; //DB作成

ところがコンテナ内でmigrateはできず。。。

次はちゃんと教材見ながらトライしてみよう。。。挑戦はまだまだ続く。。。

日を改め再チャレンジ


PostgreSQLでサイトの表示まではできたので、再度チャレンジ。(以下参考。)

https://chobimusic.com/laradock_postgresql/

compose upの前に.envファイルを編集。

APP_CODE_PATH_HOST=../laravel #laravelのプロジェクトファイル名に書き換え
DATA_PATH_HOST=../data #複数データを参照してしまう可能性があるため
COMPOSE_PROJECT_NAME=docker_mysql #dockerのコンテナ名を変更
MYSQL_VERSION=5.7 #latestから変更
DB_HOST=mysql #追記

さらにdocker-compose.ymlのphpmyadminのポート番号を8081に変更。(MySQL Notifierも毎回起動するので停止させておく。)

コマンド実行。もはや1つもdoneされない状況に。。。泣 前は表示されなかったのに。

$ docker-compose up -d nginx mysql workspace phpmyadmin

【ERROR: Service 'php-fpm' failed to build: The command '/bin/sh -c if [ ${INSTALL_IMAGEMAGICK} = true ]; then apt-get install -y libmagickwand-dev imagemagick && pecl install imagick && docker-php-ext-enable imagick ;fi' returned a non-zero code: 100】でサービス 'php-fpm'の構築に失敗しているとのこと。


以下の記事を参考に、php-fpmディレクトリのDockerfileにて以下をImageMagickの欄に追記。再度試したところdoneと表示◎

http://domwp.hatenablog.com/entry/2019/01/30/151146

apt-get update && \ 

laravelのバージョンを教本だと5.5のところあえて6.8で今回はチャレンジ。成功。

$ docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "6.8.*"
Application key set successfully.

Laravelアプリ トップ画面 http://localhost/
phpmyadmin トップ画面 http://localhost:8081/

以下でphpmyadminにログイン。DBにdocker_mysqlがあること確認。

サーバ名:mysql
ユーザー名:root
パスワード:root

Laravel側の.envファイルを編集。

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=docker_mysql
DB_USERNAME=root
DB_PASSWORD=root

コントローラー作成


コントローラー作成はOK
$ docker-compose exec workspace php artisan make:controller ArticleController
Controller created successfully.

DB作成


マイグレーションファイルの作成。
$ docker-compose exec workspace php artisan make:migration create_articles_table --create=articles
Created Migration: 2020_03_24_092458_create_articles_table

マイグレート。初めてマイグレートに成功◎laravel側の.envファイルをrootユーザーで記入したからっぽい。
$ docker-compose exec workspace php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.13 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.13 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.07 seconds)
Migrating: 2020_03_24_092458_create_articles_table
Migrated: 2020_03_24_092458_create_articles_table (0.05 seconds)

これでやっとアプリ制作に取り掛かれるようになった。。。泣
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

gem install mysql2エラー(Error installing mysql2)

mysql2をインストールした際エラーが出たため、情報共有します。

インストールコマンド

gem install mysql2

エラー内容

Building native extensions. This could take a while...
ERROR:  Error installing mysql2:
    ERROR: Failed to build gem native extension.

    current directory: /Users/aki/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/ext/mysql2
/Users/aki/.rbenv/versions/2.7.0/bin/ruby -I /Users/aki/.rbenv/versions/2.7.0/lib/ruby/2.7.0 -r ./siteconf20200324-90394-m50btx.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using mysql_config at /usr/local/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... yes
checking for SSL_MODE_PREFERRED in mysql.h... yes
checking for SSL_MODE_REQUIRED in mysql.h... yes
checking for SSL_MODE_VERIFY_CA in mysql.h... yes
checking for SSL_MODE_VERIFY_IDENTITY in mysql.h... yes
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... no
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /usr/local/Cellar/mysql/8.0.19/lib
-----
creating Makefile

current directory: /Users/aki/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/aki/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3/ext/mysql2
make "DESTDIR="
compiling client.c
client.c:787:14: warning: incompatible pointer types passing 'VALUE (void *)' (aka 'unsigned long (void *)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long (*)(unsigned long)') [-Wincompatible-pointer-types]
  rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0);
             ^~~~~~~~~~~~~
/Users/aki/.rbenv/versions/2.7.0/include/ruby-2.7.0/ruby/ruby.h:1988:25: note: passing argument to parameter here
VALUE rb_rescue2(VALUE(*)(VALUE),VALUE,VALUE(*)(VALUE,VALUE),VALUE,...);
                        ^
client.c:795:16: warning: incompatible pointer types passing 'VALUE (void *)' (aka 'unsigned long (void *)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long (*)(unsigned long)') [-Wincompatible-pointer-types]
    rb_rescue2(do_query, (VALUE)&async_args, disconnect_and_raise, self, rb_eException, (VALUE)0);
               ^~~~~~~~
/Users/aki/.rbenv/versions/2.7.0/include/ruby-2.7.0/ruby/ruby.h:1988:25: note: passing argument to parameter here
VALUE rb_rescue2(VALUE(*)(VALUE),VALUE,VALUE(*)(VALUE,VALUE),VALUE,...);
                        ^
2 warnings generated.
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/aki/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/mysql2-0.5.3 for inspection.
Results logged to /Users/aki/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/extensions/x86_64-darwin-19/2.7.0/mysql2-0.5.3/gem_make.out

原因

どうやらsslが見つからないとのこと。

library not found for -lssl

とりあえずインストールはされていたため、アップグレード。

brew upgrade openssl

すでにインストールされていた。

Updating Homebrew...
Warning: openssl 1.1.1d already installed

gem installにオプションを付けインストールしてみることにしたら実行できた!

gem install mysql2 -v '0.5.2' -- --with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include

まとめ

SSLのエラーがgithubでも起こったため、一度集中的に調べて記事にしておこうと思います。

参考

もはやこのページの通り実行しただけです笑
githubページ

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

2. データベースにどんな属性がはいるのか

どんな値がデータベースに入るのか

Googleのスプレッドシートを用いて,どんな値がデータベースに入るのかを想像して書きました.ここにスプレッドシートを置いておきます.

テーブルは
・ユーザ情報の格納:userテーブル
・やわらかさの格納:yawarakasaテーブル
の2つ用意しました.

Tables_in_yawarakasaapp
user
yawarakasa

userテーブルには下記のような情報が入ると仮定し,

user_id sex
Hochiko f
Kuno f
mama f
papa m

yawarakasaテーブルには下記の情報が入ると仮定してみました.

user_id year month day yawarakasa
Kuno 2020 2 24 30
mama 2020 2 24 31
Kuno 2020 2 26 28
papa 2020 2 27 33

Webアプリ上でユーザが年月日を入力すると,その日のそのユーザのやわらかさを取ってくる感じをイメージしました.

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

Xojo で Web+DBアプリを作ってみる (MySQL/MariaDB編)

「Xojo で Web+DBアプリを作ってみる」
https://qiita.com/nanbuwks/items/2cefc72528a16d60a329

では SQLite を使いましたが、MySQL(MariaDB)で試してみます。

データベースの用意

「MariaDB on Ubuntu18.04 LTS」
https://qiita.com/nanbuwks/items/c98c51744bd0f72a7087

のようにして、インストールします。

アプリ作成

最初のメニューでWebを選びます。
image.png

App を選び、メニューバーの Insert-Property で Name を db, Typeを MySQLCommunityServer とします。

もう一度 App を選び、Insert-Event Handler-Open で以下を書く

self.db = New MySQLCommunityServer
self.db.Host = "127.0.0.1"
self.db.UserName = "webdb"
self.db.Password = "password"
self.db.DatabaseName = "test"
Try
  self.db.Connect
  // proceed with database operations here..
Catch error As DatabaseException
  MessageBox("The database couldn't be opened. Error: " + error.Message)
  Return
End Try
try
  self.db.SQLExecute("set names utf8 collate utf8_general_ci")
  self.db.SQLExecute("set character set utf8")
  self.db.SQLExecute("use test")
Catch error as DatabaseException
  MessageBox error.Message
end try

WebPage1に移ってText Fieldを2つ、ボタンを1つドラッグドロップします。ボタンをダブルクリックしてActionに以下を書きます。

var Record as new DatabaseRow
dim temp as string
temp = tempField.Text
dim hemi as string
hemi = hemiField.Text
try
  app.db.ExecuteSQL("INSERT INTO sensor ( sensor,temp,hemi ) VALUES (1,"+temp+","+hemi+");")
Catch error as DatabaseException
  MessageBox error.Message
end try

次に、ボタンをもう一つ置き、ダブルクリックしてActionに以下のコードを書きます。

var temp,hemi as double
var rs as RowSet
try
  rs =app.db.SelectSQL("SELECT id,sensor,temp,hemi FROM sensor")
Catch e as DatabaseException
  messagebox e.Message
end try
try
  for each row as databaserow in rs
    temp = val(row.column("temp").stringvalue)
    hemi = val(row.column("hemi").stringvalue)
    Listbox1.AddRow( row.column("id").StringValue,row.column("sensor"),format(temp,"##.#"),format(hemi,"##.#") )
  next
Catch e as DatabaseException
  messagebox e.Message
end try

最後に、List Box を WebPage1 に置き、カラム数を4にします。

ラベルをつけたりOKを書き直したりして体裁を整えます。

image.png

実行

本来は、Playボタンを押すと内蔵Webサーバが起動し、ブラウザが自動で起動してアプリ画面が表示される。
今回は、コーディングは Windowsで、実行は Linuxサーバで動かした。MySQL/MariaDB も Linuxで動かしている。
こうした理由は日本語でのMySQL/MariaDB を Xojo で使う場合 Windowsでは問題があり、Xojo IDEがLinuxでは問題があるからである。

ローカルLAN同士で接続し、以下のように実行する。
「Xojo でリモート開発」
https://qiita.com/nanbuwks/items/4743756186060c3c3d20

Webアプリであるが、 Remode Debugger Desktopでなければ動かなかった。
リモートでなければWebブラウザが自動で起動するが、今回は手動でWebブラウザを http://(LinuxサーバのIPアドレス):8080
を開く。

image.png

デスクトップアプリと違うところ

「ojo で Web+DBアプリを作ってみる (SQLite編)」と同じ内容:

  • WIndow1 → WebPageとなる
  • ListBox という名前は予約されているためListBox1という名前にした
  • テキストフィールドを使ったhemiFieldの値: hemiField.Value は hemiField.Text になる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Flask: [root] Error: Can't locate revision identified by 'XXXXXXX' が出てしまい、migrateできないとき。

エラーの発生

migration ファイルを消して再度flask db init -> flask db migrateした際、

(flask_env) C:\Users\ryosu\Desktop\sample_2>flask db migrate
C:\Users\ryosu\Anaconda3\envs\flask_env\lib\site-packages\pymysql\cursors.py:170: Warning: (3719, "'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.")
  result = self._query(query)
C:\Users\ryosu\Anaconda3\envs\flask_env\lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\x93\\x8C\\x8B\\x9E (...' for column 'VARIABLE_VALUE' at row 1")
  result = self._query(query)
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
ERROR [root] Error: Can't locate revision identified by 'e7c58547f941

が発生しmigrateできなくなってしまった。

解消方法

mysqlでdbを覗くと、alembic_versionというテーブルが残っていた。

mysql> show tables;
+---------------------+
| Tables_in_sample_db |
+---------------------+
| alembic_version     |
+---------------------+
1 row in set (0.00 sec)

これをdropし、

mysql> drop table alembic_version;
Query OK, 0 rows affected (0.18 sec)

再び、migrateすると無事エラーが解消した。

C:\Users\ryosu\Anaconda3\envs\flask_env\lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\x93\\x8C\\x8B\\x9E (...' for column 'VARIABLE_VALUE' at row 1")
  result = self._query(query)
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'infos'
Generating C:\Users\ryosu\Desktop\sample_2\migrations\versions\3b7a65a2d497_.py ...  done

エラーを検索しても英語の記事しか出てこなかったため、メモとして残しておきます。

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