20190929のMySQLに関する記事は7件です。

CakePHP3 アソシエーションの設定済みテーブル/ドット記法/contain済みデータを表示させるまで(19/9/29)

■今回、画像投稿型の...

...あるテーマに沿ったサイトを
ポートフォリオとして制作中に確認できた、
今後に活かせる(未来の自分をハマらせない)ちょっとした内容ですが、
しっかり記録を残しておこうと思います。

■不明だったこと■
公式ドキュメントを参照にcontain、belongs to、hasmanyに
ついて学び、Model(テーブル)と、controllerに記述はしたものの、
「では、ctpファイル(表示させる部分)にはどのように記述すればいいの?」
ということがわからない状況が続いていました。

■解消できたこと■
特定のキーワード(Icesテーブル内の特定フィールド)を元に
「検索」された「記事」に「他ユーザが投稿した、投稿済みコメント」
を表示させ、さらに「投稿済みコメントの投稿ユーザ」の「ニックネーム」
を表示させ、さらにその「ニックネーム」をクリックすると、
そのユーザーの詳細情報に画面遷移させることができるようになりました。

■テーブル■
Users(ユーザ情報が入る:ここにニックネーム有り)
Ices(ブログ記事が入る)
Comments(ブログ記事に対して他ユーザがコメント時のデータが入る)

■環境■
AWS Cloud9:無料枠
MySQL:ver5.7.26
CakePHP:ver3.8.2
PHP:ver7.2.19

■結果■

ctpファイル内に下記のように記述することで、
上記の「解消できたこと」につながりました。

/src/Template/Ices/ranking.ctp
<?php foreach ($ices as $ice): ?>
     // // 一部省略  // //
<h3>ここからコメント</h3>
<?php if ($ice->comments): ?>
<p><?= h($ice->comments[0]->comment) ?></p>

  //↓このpタグ内がポイント//
<p>BY<?= $this->Html
->link( h($ice->comments[0]->user->nickname),
['controller' => 'Users', 
'action' => 'view', 
$ice->comments[0]->user['id']]) ?></p>
  //↑このpタグ内がポイント//


<?php else: ?>
<p>コメントはまだありません。</p>

<?php endif ?>

<?php endforeach; ?>

▽関係アリと思われる部分と解消方法▽

/src/Model/Table/CommentsTable.phpの、
foreignKeyがあったことで、Commentsテーブルに
紐づくUsersテーブルの情報が引っ張ってこれなかったようです。
そのモデル内の修正と、ctpファイルへの記述を変更し、
解決に至りました。

/src/Model/Table/UsersTable.php
parent::initialize($config);
        // // 一部省略  // //
        $this->hasMany('Comments',[
            'foreignKey' => 'user_id'
        ]);
        $this->hasMany('Ices', [
            'foreignKey' => 'user_id'
        ]);    
        $this->hasMany('Comments', [
            'foreignKey' => 'user_id'
        ]);
/src/Model/Table/IcesTable.php
public function initialize(array $config)
    {
          // // 一部省略  // //
        $this->belongsTo('Users', [
            'foreignKey' => 'user_id',
            'joinType' => 'INNER'
        ]);
        $this->hasMany('Comments', [
            'foreignKey' => 'ice_id'
        ]);
    }
/src/Model/Table/CommentsTable.php
public function initialize(array $config)
    {
          // // 一部省略  // //

        $this->belongsTo('Ices', [
            'foreignKey' => 'ice_id',
            'joinType' => 'INNER'
        ]);

        $this->belongsTo('Users', [
            //'foreignKey' => 'id',
            //↑これがあったから、ひっぱってこれなかった
            'joinType' => 'INNER'
        ]);
    }
/src/Controller/IcesController.php
public function search()
    {
        $ices = $this->Ices->find('all');
        $manufacturer = isset($this->request->query['manufacturer']) ? $this->request->query['manufacturer'] : null;
        $keyword = isset($this->request->query['keyword']) ? $this->request->query['keyword'] : null;

        if($manufacturer){
            $where = ['Ices.manufacturer' => $manufacturer];

            if ($keyword) {
            $where['OR']['Ices.ice_fraver LIKE'] = "%$keyword%";
            $where['OR']['Ices.simple_comment LIKE'] = "%$keyword%";
            }

            $ices = $this->Ices->find();


            $ices->where($where)
            //↓ここがポイント!!
            ->contain(['Comments.Users','Users'])
            //"Comments.Users"の意味は...
            //Icesテーブルに紐づく、
            //Commentsテーブルの情報と、
            //Commentsテーブルに紐づく、Usersテーブルの情報。
            //という意味で、
            //"Users"の部分は、
            //Icesテーブルに紐づく、
            //Userテーブルの情報を含む...
            //という意味になる。
            ->all();


            $this->set('manufacturer', $manufacturer);
            $this->set('keyword', $keyword);
            $this->set('ices', $this->paginate($ices));
            $this->render('ranking');
    }


    }

▽参考マニュアル(CakePHP公式ドキュメント)

https://book.cakephp.org/3.0/ja/orm/retrieving-data-and-resultsets.html
https://book.cakephp.org/3.0/ja/orm/associations.html

■最後に自分へ一言

debugをした結果、そこに取得希望のフィールドが表示されていなければ、
必ず取得の方法から見直すこと。
そうすれば、あとは表示方法を模索するだけ。

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

最近よく使っているDocker構成の備忘録 (NodeJS+Redis+MySQL)

はじめに

この記事は最近Dockerをよく使うようになってきて、
開発環境を作っては捨て作っては捨てを繰り返しつつ、いろいろ試しているうちに
個人的によく使いそうな構成が見えてきたので、それをメモとして残しておく目的で記載しています。

アーキテクチャ

NodeJS + Redis + MySQLによる構成で作っていきます。
主な内訳は以下の通りです。

利用目的
NodeJS webアプリケーション
MySQL ユーザー等の主なデータ
Redis セッション,キャッシュ

今回セッションとキャッシュをどちらもRedisで管理してしまっていますが、
分けるソリューションもあると思います。
一例としては、キャッシュとかはDynamoDBでセッション管理はRedisに保存みたいな感じですかね。
自分が作る程度の環境だとそこまで分ける必要性を感じなかったので、すべてRedisで管理してました。

ディレクトリ構成

このあとdocker-compose.ymlを記載しますが、
今回は以下のディレクトリ構成を前提で進めています。

├── data
│   ├── mysql
│   └── redis
├── docker-compose.yml
├── mysql
│   └── Dockerfile
├── app
│   ├── Dockerfile
│   ├── app.js
│   ├── bin
│   │   └── www
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   │   ├── images
│   │   ├── javascripts
│   │   └── stylesheets
│   │       └── style.css
│   ├── routes
│   │   ├── index.js
│   │   └── users.js
│   └── views
│       ├── error.jade
│       ├── index.jade
│       └── layout.jade
└── redis
    └── Dockerfile

docker-compose.yml

今回は、Docker-Composeを使ってNodeJS、MySQL、Redisのそれぞれでコンテナ立ち上げていく形にしていきます。
docker-composeの内容は以下の通りです。

docker-compose.yml
version: '3'

services:
  app:
    build:
      context: .
      dockerfile: ./app/Dockerfile
    depends_on:
      - mysql
      - redis
    ports:
      - '3000:3000'
    tty: true
    container_name: node_app

  mysql:
    build:
      context: .
      dockerfile: ./mysql/Dockerfile
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_USER: user
      MYSQL_PASSWORD: hogehoge
      MYSQL_DATABASE: testdb
    volumes:
      - ./data/mysql:/var/lib/mysql
    container_name: mysql

  redis:
    build:
      context: .
      dockerfile: ./redis/Dockerfile
    restart: always
    volumes:
      - ./data/redis:/data
    container_name: redis

servicesに対してwebアプリケーションや他のミドルウェアのDockerイメージに関する設定内容を記載しています。
appのところにはdepends_onがありますが、これは記載されている他のイメージとの依存関係を示すものになっています。依存関係のあるものが解決してからappの内容が動作します。
それぞれbuildのところで、どのDockerfileを使用してDockerイメージをbuildするかを設定しているのがわかると思うので、Dockerfileも記載しましょう。

./app/Dockerfile

./app/Dockerfile
FROM node:latest

WORKDIR /home/app

COPY ./app/package*.json ./

RUN npm install

COPY ./app ./

EXPOSE 3000

./mysql/Dockerfile

./mysql/Dockerfile
FROM mysql:5.7

# ADD ./mysqld.cnf /etc/mysql/mysql.conf.d/mysqld.cnf

EXPOSE 3306

./redis/Dockerfile

./redis/Dockerfile
FROM redis

# COPY redis.conf /usr/local/etc/redis/redis.conf

EXPOSE 6379

実行

docker-compose.ymlのあるディレクトリで実行します。

build

$ docker-compose build

起動

$ docker-compose up -d

exec

# nodeのコンテナ
$ docker-compose exec app bash

# redisのコンテナ
$ docker-compose exec redis bash

# mysqlのコンテナ
$ docker-compose exec mysql bash

ここに記載していないコマンドはこちらの方の記事が参考になります。
docker-compose コマンドまとめ

おわりに

個人的に利用することの多そうな環境をメモがてら書いていきましたが、
間違いやよりよい方法があればぜひ教えてください?‍♀️

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

[初心者]Docker+Rails+MySQLでの環境構築の記録

はじめに

cloud9やvagrant以外にも
Dockerを使って環境構築してみたいと思い、勉強をしてみました!
Docker環境構築をする上で行った事を振り返ってまとめています。

Dockerについて

  • ホストOSのカーネルを使用している為、軽量で起動が高速
  • 複数人で開発する時に開発環境を統一しやすい
  • そのまま本番サーバーにデプロイする事ができる

などのメリットがあると知り、
様々の方のqiita記事など参考に環境構築に取り組んでみました。

環境

  • Mac OS
  • Ruby 2.6.3
  • Rails 5.2.3
  • MySQL 8.0

【1】作業ディレクトリの作成、移動

$ mkdir sample
$ cd sample

【2】Dockerfileの作成

$ vi Dockerfile
Dockerfile
FROM ruby:2.6.3
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /sample
WORKDIR /sample
ADD Gemfile /sample/Gemfile
ADD Gemfile.lock /sample/Gemfile.lock
RUN bundle install
ADD . /sample

【3】Gemfile、空のGemfile.lockを作成

$ vi Gemfile
Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.3'
$ touch Gemfile.lock

【4】docker-compose.ymlの作成

$ vi docker-compose.yml
docker-compose.yml
version: '3'
services:
  db:
    image: mysql
    command: mysqld --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_USER: root
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3316:3306'
    volumes:
      - ./db/mysql/volumes:/var/lib/mysql


  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/sample
    ports:
      - "3000:3000"
    depends_on:
      - db

【5】Rails newを実行する

$ docker-compose run web rails new . --force --database=mysql

【6】イメージを再ビルドする

$ docker-compose build

【7】config/database.ymlの設定

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  host: localhost

database.ymlが上記のようになっているので
下記のように書き換える。

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db

【8】サービスを起動する

$ docker-compose up -d

【9】DBを作成する

$ docker-compose run web rails db:create

【10】アクセスしてサーバーの起動を確認する

http://localhost:3000にアクセスしてRailsのトップページが表示されたら完成です。

その後、サーバーを止める時はdocker-compose stopとします。

docker-rails1.png

感じたこと

まだまだDockerに関する知識は浅いですがとにかく環境を構築する事ができました!

環境構築中MySQLの認証プラグインのエラーが発生してかなり苦戦したのですが、
どうやらMySQL8.0は
【4】docker-compose.ymlの作成のところで
command: mysqld --default-authentication-plugin=mysql_native_password
を書かないとエラーが出てしまうようです。
このエラーを解決する為に様々な方法を試していくうちに
MySQLの権限エラーが新たに出るなどして泥沼にハマっていき
10時間ぐらいかかって解決して何とか環境構築できました(汗)

環境構築はとりあえずできましたが
何がどうなっているのかなどまだまだDockerを理解できていない部分が多いので
今後更に深く学習してみようと感じました。

参考

[Rails] DockerでRails + MySQLの開発環境をつくる手順
丁寧すぎるDocker-composeによるrails + MySQL on Dockerの環境構築(Docker for Mac)
Docker Composeのインストール方法(CentOS7.3)

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

【初心者】Docker+Rails+MySQLでの環境構築の記録

はじめに

cloud9やvagrant以外にも
Dockerを使って環境構築してみたいと思い、勉強をしてみました!
Docker環境構築をする上で行った事を振り返ってまとめています。

Dockerについて

  • ホストOSのカーネルを使用している為、軽量で起動が高速
  • 複数人で開発する時に開発環境を統一しやすい
  • そのまま本番サーバーにデプロイする事ができる

などのメリットがあると知り、
様々の方のqiita記事など参考に環境構築に取り組んでみました。

環境

  • Mac OS
  • Ruby 2.6.3
  • Rails 5.2.3
  • MySQL 8.0

【1】作業ディレクトリの作成、移動

$ mkdir sample
$ cd sample

【2】Dockerfileの作成

$ vi Dockerfile
Dockerfile
FROM ruby:2.6.3
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /sample
WORKDIR /sample
ADD Gemfile /sample/Gemfile
ADD Gemfile.lock /sample/Gemfile.lock
RUN bundle install
ADD . /sample

【3】Gemfile、空のGemfile.lockを作成

$ vi Gemfile
Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.3'
$ touch Gemfile.lock

【4】docker-compose.ymlの作成

$ vi docker-compose.yml
docker-compose.yml
version: '3'
services:
  db:
    image: mysql
    command: mysqld --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_USER: root
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3316:3306'
    volumes:
      - ./db/mysql/volumes:/var/lib/mysql


  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/sample
    ports:
      - "3000:3000"
    depends_on:
      - db

【5】Rails newを実行する

$ docker-compose run web rails new . --force --database=mysql

【6】イメージを再ビルドする

$ docker-compose build

【7】config/database.ymlの設定

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  host: localhost

database.ymlが上記のようになっているので
下記のように書き換える。

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db

【8】サービスを起動する

$ docker-compose up -d

【9】DBを作成する

$ docker-compose run web rails db:create

【10】アクセスしてサーバーの起動を確認する

http://localhost:3000にアクセスしてRailsのトップページが表示されたら完成です。

その後、サーバーを止める時はdocker-compose stopとします。

docker-rails1.png

感じたこと

まだまだDockerに関する知識は浅いですがとにかく環境を構築する事ができました!

環境構築中MySQLの認証プラグインのエラーが発生してかなり苦戦したのですが、
どうやらMySQL8.0は
【4】docker-compose.ymlの作成のところで
command: mysqld --default-authentication-plugin=mysql_native_password
を書かないとエラーが出てしまうようです。
このエラーを解決する為に様々な方法を試していくうちに
MySQLの権限エラーが新たに出るなどして泥沼にハマっていき
10時間ぐらいかかって解決して何とか環境構築できました(汗)

環境構築はとりあえずできましたが
何がどうなっているのかなどまだまだDockerを理解できていない部分が多いので
今後更に深く学習してみようと感じました。

参考

[Rails] DockerでRails + MySQLの開発環境をつくる手順
丁寧すぎるDocker-composeによるrails + MySQL on Dockerの環境構築(Docker for Mac)
Docker Composeのインストール方法(CentOS7.3)

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

DjangoでGAEのMySQLと接続する時にポートが埋まっているよと言われた時の対処法

終わってみれば簡単な思い込みだったのですが、同じようなことが起こった時にために残しておきます。

環境

MacOS Mojave 10.14
Python 3.7.3
Django 2.2

手順

手順自体は公式に載っているのですが、ここにざっくり書くと、
1.APIを有効にする
2.プロキシをインストールする
3. サービス アカウントを作成する
4. プロキシを開始する
5. クライアント セッションを開始する
と言う流れなのですが、

僕の場合は
4のプロキシを開始する手順での、
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306

というコマンドを叩いてもポートがすでに埋まってるよ!
というメッセージが返ってきたので、

とりあえず現在使われているポートを調べるために

lsof -i :[PORT番号]

をしてみると既に使用しているポートの一覧が表示されるので、埋まっているポートを終わらせたい時には

kill -9 PID値

でポートを閉じられるのでkillしてみた後に再び
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306

コマンドを叩いてみるとつながりました。

以上です。

 追記

この方法でOperation not Permittedと表示された時の解決策と原因について書きました

この記事の方法で上手くいかないときはこちらも試してみてください!

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

Debezium で MySQL の変更データを取得する

はじめに

Debezium はDBの変更をイベントストリームに変換することができる分散プラットホームです。例えば MySQL に対して行った Update を 行レベルで確認することができます(Json形式)。

~省略~
  "payload": {
    "before": {
      "id": 100,
      "first_name": "Oliver",
      "last_name": "Jack",
      "email": "jack@test.com"
    },
    "after": {
      "id": 100,
      "first_name": "Oliver",
      "last_name": "Harry",
      "email": "harry@test.com"
    }
~省略~

Debezium は Apache Kafka をベースに実装されており、データ変更の履歴を Kafkaログに記録します。アプリケーションが停止した場合でも、再起動すれば中断したイベントから変更を確認できます。
さらに、MySQL、PostgreSQL、MongoDB、SQL Server、Oracle など多くの DB に対応しています。

チュートリアルがあるので試してみました。
https://debezium.io/documentation/reference/0.9/tutorial.html

チュートリアルが長いので、なるべく簡略化して書きたいと思います。
チュートリアルでは MySQL の変更データを取得する内容になっています。

実行環境

AWS EC2 Linux2
事前に Docker のインストールが必要。

セットアップ

Debezium は ZooKeeper、Kafka、Debeziumコネクタサービスの3つが主なコンポーネントとなります。
動作を確認するために docker run毎に新しいターミナルを立ち上げてください。docker run のオプションで -it を指定することでインタラクティブにターミナルに内容が表示されます。また、--rm を指定することでチュートリアルが終わり停止させたときに削除されます。

zookeeper 起動

zookeeper は、分散処理システムを構築するためのミドルウェアです。
Kafka は複数台の Kafka サーバーでクラスターを組むことができ、各 Kafka サーバーを連携させるのが zookeeperです。

docker run -it --rm --name zookeeper -p 2181:2181 -p 2888:2888 -p 3888:3888 debezium/zookeeper:0.9

Kafka 起動

Kafka は分散メッセージキューです。一時的にデータ保持するミドルウェアです。

docker run -it --rm --name kafka -p 9092:9092 --link zookeeper:zookeeper debezium/kafka:0.9

MySQL 起動

MySQL はリレーショナルデータベースです。
今回はチュートリアルのため既にテーブルなどが作成されたイメージを使用します。

docker run -it --rm --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=debezium -e MYSQL_USER=mysqluser -e MYSQL_PASSWORD=mysqlpw debezium/example-mysql:0.9

MySQL command line client 起動

MySQL を操作するためにコマンドラインクライアントを起動します。

docker run -it --rm --name mysqlterm --link mysql --rm mysql:5.7 sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'

MySQL command line client にてuse inventory;を実行し、次にshow tables; を実行すると、すでにテーブルが存在することが分かります。

Kafka Connect 起動

Kafka Connect はKafkaと周辺のシステムのストリームデータをやりとりするための通信規格とライブラリとツールです。

docker run -it --rm --name connect -p 8083:8083 -e GROUP_ID=1 -e CONFIG_STORAGE_TOPIC=my_connect_configs -e OFFSET_STORAGE_TOPIC=my_connect_offsets -e STATUS_STORAGE_TOPIC=my_connect_statuses --link zookeeper:zookeeper --link kafka:kafka --link mysql:mysql debezium/connect:0.9

curl -H "Accept:application/json" localhost:8083/ を実行して値が返ってくれば Kafka Connect REST API が起動しています。

MySQL モニタリング

connector から DB、Kafka に接続するために必要な情報を設定します。

curl -i -X POST -H "Accept:application/json" -H "Content-Type:application/json" localhost:8083/connectors/ -d '{ "name": "inventory-connector", "config": { "connector.class": "io.debezium.connector.mysql.MySqlConnector", "tasks.max": "1", "database.hostname": "mysql", "database.port": "3306", "database.user": "debezium", "database.password": "dbz", "database.server.id": "184054", "database.server.name": "dbserver1", "database.whitelist": "inventory", "database.history.kafka.bootstrap.servers": "kafka:9092", "database.history.kafka.topic": "dbhistory.inventory" } }'

HTTP/1.1 201 Created と表示されることを確認します。

コマンドで設定されたことを確認します。

curl -i -X GET -H "Accept:application/json" localhost:8083/connectors/inventory-connector

以上でセットアップは完了です。

データ変更時の動作確認

MySQL のデータを変更して変更内容が取得できるか見てみます。

Kafka にメッセージが入ったかを確認するために watcher を起動します。

docker run -it --name watcher --rm --link zookeeper:zookeeper --link kafka:kafka debezium/kafka:0.9 watch-topic -a -k dbserver1.inventory.customers

初期接続時にはテーブル作成時からのすべての変更を読み取るため、全データが変更データとして表示されます。次回からは読み取り済みのログの続きから読み取るようになっています。

WARNING: Using default BROKER_ID=1, which is valid only for non-clustered installations.
Using ZOOKEEPER_CONNECT=172.17.0.2:2181
Using KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://172.17.0.7:9092
Using KAFKA_BROKER=172.17.0.3:9092
Contents of topic dbserver1.inventory.customers:
{"schema":{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"}],"optional":false,"name":"dbserver1.inventory.customers.Key"},"payload":{"id":1001}}        {"schema":{"type":"struct","fields":[{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"},{"type":"string","optional":false,"field":"first_name"},{"type":"string","optional":false,"field":"last_name"},{"type":"string","optional":false,"field":"email"}],"optional":true,"name":"dbserver1.inventory.customers.Value","field":"before"},{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"},{"type":"string","optional":false,"field":"first_name"},{"type":"string","optional":false,"field":"last_name"},{"type":"string","optional":false,"field":"email"}],"optional":true,"name":"dbserver1.inventory.customers.Value","field":"after"},{"type":"struct","fields":[{"type":"string","optional":true,"field":"version"},{"type":"string","optional":true,"field":"connector"},{"type":"string","optional":false,"field":"name"},{"type":"int64","optional":false,"field":"server_id"},{"type":"int64","optional":false,"field":"ts_sec"},{"type":"string","optional":true,"field":"gtid"},{"type":"string","optional":false,"field":"file"},{"type":"int64","optional":false,"field":"pos"},{"type":"int32","optional":false,"field":"row"},{"type":"boolean","optional":true,"default":false,"field":"snapshot"},{"type":"int64","optional":true,"field":"thread"},{"type":"string","optional":true,"field":"db"},{"type":"string","optional":true,"field":"table"},{"type":"string","optional":true,"field":"query"}],"optional":false,"name":"io.debezium.connector.mysql.Source","field":"source"},{"type":"string","optional":false,"field":"op"},{"type":"int64","optional":true,"field":"ts_ms"}],"optional":false,"name":"dbserver1.inventory.customers.Envelope"},"payload":{"before":null,"after":{"id":1001,"first_name":"Sally","last_name":"Thomas","email":"sally.thomas@acme.com"},"source":{"version":"0.9.5.Final","connector":"mysql","name":"dbserver1","server_id":0,"ts_sec":0,"gtid":null,"file":"mysql-bin.000003","pos":154,"row":0,"snapshot":true,"thread":null,"db":"inventory","table":"customers","query":null},"op":"c","ts_ms":1569744224564}}
{"schema":{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"}],"optional":false,"name":"dbserver1.inventory.customers.Key"},"payload":{"id":1002}}        {"schema":{"type":"struct","fields":[{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"},{"type":"string","optional":false,"field":"first_name"},{"type":"string","optional":false,"field":"last_name"},{"type":"string","optional":false,"field":"email"}],"optional":true,"name":"dbserver1.inventory.customers.Value","field":"before"},{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"},{"type":"string","optional":false,"field":"first_name"},{"type":"string","optional":false,"field":"last_name"},{"type":"string","optional":false,"field":"email"}],"optional":true,"name":"dbserver1.inventory.customers.Value","field":"after"},{"type":"struct","fields":[{"type":"string","optional":true,"field":"version"},{"type":"string","optional":true,"field":"connector"},{"type":"string","optional":false,"field":"name"},{"type":"int64","optional":false,"field":"server_id"},{"type":"int64","optional":false,"field":"ts_sec"},{"type":"string","optional":true,"field":"gtid"},{"type":"string","optional":false,"field":"file"},{"type":"int64","optional":false,"field":"pos"},{"type":"int32","optional":false,"field":"row"},{"type":"boolean","optional":true,"default":false,"field":"snapshot"},{"type":"int64","optional":true,"field":"thread"},{"type":"string","optional":true,"field":"db"},{"type":"string","optional":true,"field":"table"},{"type":"string","optional":true,"field":"query"}],"optional":false,"name":"io.debezium.connector.mysql.Source","field":"source"},{"type":"string","optional":false,"field":"op"},{"type":"int64","optional":true,"field":"ts_ms"}],"optional":false,"name":"dbserver1.inventory.customers.Envelope"},"payload":{"before":null,"after":{"id":1002,"first_name":"George","last_name":"Bailey","email":"gbailey@foobar.com"},"source":{"version":"0.9.5.Final","connector":"mysql","name":"dbserver1","server_id":0,"ts_sec":0,"gtid":null,"file":"mysql-bin.000003","pos":154,"row":0,"snapshot":true,"thread":null,"db":"inventory","table":"customers","query":null},"op":"c","ts_ms":1569744224564}}
{"schema":{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"}],"optional":false,"name":"dbserver1.inventory.customers.Key"},"payload":{"id":1003}}        {"schema":{"type":"struct","fields":[{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"},{"type":"string","optional":false,"field":"first_name"},{"type":"string","optional":false,"field":"last_name"},{"type":"string","optional":false,"field":"email"}],"optional":true,"name":"dbserver1.inventory.customers.Value","field":"before"},{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"},{"type":"string","optional":false,"field":"first_name"},{"type":"string","optional":false,"field":"last_name"},{"type":"string","optional":false,"field":"email"}],"optional":true,"name":"dbserver1.inventory.customers.Value","field":"after"},{"type":"struct","fields":[{"type":"string","optional":true,"field":"version"},{"type":"string","optional":true,"field":"connector"},{"type":"string","optional":false,"field":"name"},{"type":"int64","optional":false,"field":"server_id"},{"type":"int64","optional":false,"field":"ts_sec"},{"type":"string","optional":true,"field":"gtid"},{"type":"string","optional":false,"field":"file"},{"type":"int64","optional":false,"field":"pos"},{"type":"int32","optional":false,"field":"row"},{"type":"boolean","optional":true,"default":false,"field":"snapshot"},{"type":"int64","optional":true,"field":"thread"},{"type":"string","optional":true,"field":"db"},{"type":"string","optional":true,"field":"table"},{"type":"string","optional":true,"field":"query"}],"optional":false,"name":"io.debezium.connector.mysql.Source","field":"source"},{"type":"string","optional":false,"field":"op"},{"type":"int64","optional":true,"field":"ts_ms"}],"optional":false,"name":"dbserver1.inventory.customers.Envelope"},"payload":{"before":null,"after":{"id":1003,"first_name":"Edward","last_name":"Walker","email":"ed@walker.com"},"source":{"version":"0.9.5.Final","connector":"mysql","name":"dbserver1","server_id":0,"ts_sec":0,"gtid":null,"file":"mysql-bin.000003","pos":154,"row":0,"snapshot":true,"thread":null,"db":"inventory","table":"customers","query":null},"op":"c","ts_ms":1569744224564}}
{"schema":{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"}],"optional":false,"name":"dbserver1.inventory.customers.Key"},"payload":{"id":1004}}        {"schema":{"type":"struct","fields":[{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"},{"type":"string","optional":false,"field":"first_name"},{"type":"string","optional":false,"field":"last_name"},{"type":"string","optional":false,"field":"email"}],"optional":true,"name":"dbserver1.inventory.customers.Value","field":"before"},{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"},{"type":"string","optional":false,"field":"first_name"},{"type":"string","optional":false,"field":"last_name"},{"type":"string","optional":false,"field":"email"}],"optional":true,"name":"dbserver1.inventory.customers.Value","field":"after"},{"type":"struct","fields":[{"type":"string","optional":true,"field":"version"},{"type":"string","optional":true,"field":"connector"},{"type":"string","optional":false,"field":"name"},{"type":"int64","optional":false,"field":"server_id"},{"type":"int64","optional":false,"field":"ts_sec"},{"type":"string","optional":true,"field":"gtid"},{"type":"string","optional":false,"field":"file"},{"type":"int64","optional":false,"field":"pos"},{"type":"int32","optional":false,"field":"row"},{"type":"boolean","optional":true,"default":false,"field":"snapshot"},{"type":"int64","optional":true,"field":"thread"},{"type":"string","optional":true,"field":"db"},{"type":"string","optional":true,"field":"table"},{"type":"string","optional":true,"field":"query"}],"optional":false,"name":"io.debezium.connector.mysql.Source","field":"source"},{"type":"string","optional":false,"field":"op"},{"type":"int64","optional":true,"field":"ts_ms"}],"optional":false,"name":"dbserver1.inventory.customers.Envelope"},"payload":{"before":null,"after":{"id":1004,"first_name":"Anne","last_name":"Kretchmar","email":"annek@noanswer.org"},"source":{"version":"0.9.5.Final","connector":"mysql","name":"dbserver1","server_id":0,"ts_sec":0,"gtid":null,"file":"mysql-bin.000003","pos":154,"row":0,"snapshot":true,"thread":null,"db":"inventory","table":"customers","query":null},"op":"c","ts_ms":1569744224564}}

データ Update

データを Update してみます。

use inventory;
UPDATE customers SET first_name='Anne Marie' WHERE id=1004;

出力結果
{
    "schema": {
        "type": "struct",
        "fields": [
            {
                "type": "struct",
                "fields": [
                    {
                        "type": "int32",
                        "optional": false,
                        "field": "id"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "first_name"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "last_name"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "email"
                    }
                ],
                "optional": true,
                "name": "dbserver1.inventory.customers.Value",
                "field": "before"
            },
            {
                "type": "struct",
                "fields": [
                    {
                        "type": "int32",
                        "optional": false,
                        "field": "id"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "first_name"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "last_name"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "email"
                    }
                ],
                "optional": true,
                "name": "dbserver1.inventory.customers.Value",
                "field": "after"
            },
            {
                "type": "struct",
                "fields": [
                    {
                        "type": "string",
                        "optional": true,
                        "field": "version"
                    },
                    {
                        "type": "string",
                        "optional": true,
                        "field": "connector"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "name"
                    },
                    {
                        "type": "int64",
                        "optional": false,
                        "field": "server_id"
                    },
                    {
                        "type": "int64",
                        "optional": false,
                        "field": "ts_sec"
                    },
                    {
                        "type": "string",
                        "optional": true,
                        "field": "gtid"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "file"
                    },
                    {
                        "type": "int64",
                        "optional": false,
                        "field": "pos"
                    },
                    {
                        "type": "int32",
                        "optional": false,
                        "field": "row"
                    },
                    {
                        "type": "boolean",
                        "optional": true,
                        "default": false,
                        "field": "snapshot"
                    },
                    {
                        "type": "int64",
                        "optional": true,
                        "field": "thread"
                    },
                    {
                        "type": "string",
                        "optional": true,
                        "field": "db"
                    },
                    {
                        "type": "string",
                        "optional": true,
                        "field": "table"
                    },
                    {
                        "type": "string",
                        "optional": true,
                        "field": "query"
                    }
                ],
                "optional": false,
                "name": "io.debezium.connector.mysql.Source",
                "field": "source"
            },
            {
                "type": "string",
                "optional": false,
                "field": "op"
            },
            {
                "type": "int64",
                "optional": true,
                "field": "ts_ms"
            }
        ],
        "optional": false,
        "name": "dbserver1.inventory.customers.Envelope"
    },
    "payload": {
        "before": {
            "id": 1004,
            "first_name": "Anne",
            "last_name": "Kretchmar",
            "email": "annek@noanswer.org"
        },
        "after": {
            "id": 1004,
            "first_name": "Anne Marie",
            "last_name": "Kretchmar",
            "email": "annek@noanswer.org"
        },
        "source": {
            "version": "0.9.5.Final",
            "connector": "mysql",
            "name": "dbserver1",
            "server_id": 223344,
            "ts_sec": 1569745138,
            "gtid": null,
            "file": "mysql-bin.000003",
            "pos": 364,
            "row": 0,
            "snapshot": false,
            "thread": 2,
            "db": "inventory",
            "table": "customers",
            "query": null
        },
        "op": "u",
        "ts_ms": 1569745138230
    }
}

実行結果の結果が長いため一部抜粋しました。変更前後のデータが取得できていることが分かります。

    "payload": {
        "before": {
            "id": 1004,
            "first_name": "Anne",
            "last_name": "Kretchmar",
            "email": "annek@noanswer.org"
        },
        "after": {
            "id": 1004,
            "first_name": "Anne Marie",
            "last_name": "Kretchmar",
            "email": "annek@noanswer.org"
        },

最後に

チュートリアルが終わったら Docker で起動した各サービスを必要に応じて停止させます。
docker run 時のオプションで --rm を指定したため、停止することで削除されます。

docker stop mysqlterm watcher connect mysql kafka zookeeper

実行しているプロセスがないことを確認して完了です。

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

“ERROR 3065 (HY000): Expression #1 of ORDER BY clause is not in SELECT list, references column ‘DB名.テーブル名.カラム名’ which is not in SELECT list; this is incompatible with DISTINCT”が出たので解決してみた

今回解決したいエラー

環境構築時にDBで以下のエラーが出た
ERROR 3065 (HY000): Expression #1 of ORDER BY clause is not in SELECT list, references column ‘DB名.テーブル名.カラム名’ which is not in SELECT list; this is incompatible with DISTINCT

今回のエラー原因

こちらの記事にある通り、mysqlの5.7からデフォルト値として追加された「ONLY_FULL_GROUP_BY」が原因と考えられる。

解決方法

方針

  • こちらの記事を見る
  • mysqlにSET @@global.sql_mode=(SELECT REPLACE(@@global.sql_mode, 'ONLY_FULL_GROUP_BY', ''));を入れて、「ONLY_FULL_GROUP_BY」を外す。

やり方

  1. 解決したいDBにアクセス
  2. 以下のコマンドを打つ
mysql> SET @@global.sql_mode=(SELECT REPLACE(@@global.sql_mode, 'ONLY_FULL_GROUP_BY', ''));

3.mysqlを再起動

参考

記事内にあるやり方とは違いますが、大変参考にさせていただきました。感謝します。

MySQLでdistinctが効かない。mysqlバージョン5.7からの変更。

Ransack の sort_link が MySQL で動作しない( incompatible with DISTINCT)

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