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

Dockerを使ってCakePHP2のブログチュートリアルの開発環境を構築しました。

1 はじめに

CakePHP2のアサインされたので、CakePHP2のブログチュートリアルをやりたいと思い、せっかくなのでDockerを使って環境構築することにしました。
OSはUbuntuで、Dockerのインストールが完了しているものとします。

2 Dockerの考え方

この前Dockerの記事を書きましたのでそれも参考にしてください。
Dockerについて理解した後、実際に導入してみました。 - Qiita

Dockerでは、Dockerイメージというものを使ってコンテナを作成します。
このDockerイメージというものの手に入れ方は2つあります。

  1. 自分でDockerFileを作成して作る。
  2. 誰かがDockerFileを作成して作られたイメージをDockerHubから持ってくる。
  3. 既にあるコンテナをイメージ化する。(非推奨)

3のやり方は、どういうコンテナかわかりづらいのであまりよくないようです。

Docker Hubで公開されているDockerイメージも、それぞれDockerfileが公開されていて、それを元に作成されたイメージです。2.のやり方は、暫定的にDockerイメージにしておきたい場合などに行うくらいが良いと思います。
引用元:Docker入門(第三回)~各種dockerコマンドとDockerイメージ作成について~

基本的には使用するDockerイメージのDockerFileは見れる状態にしておくのが良いみたいですね。
実際に、DockerHubに公開されているイメージのページにいくと、DockerFileが書かれていることが多いです。

そして、DockerHubには様々なイメージが置いてあるので、もはや自分でDockerFileを書くのは面倒くさいです。
できればDockerHubからイメージを持ってきて楽したいですね。



そう思っていた時期が僕にもありました。

・結局細かな設定は自分で行う。
・DockerHubで共有しようがDockerfileの内容を共有しようがあんまり手間が変わらない。

等の理由で、結局自分でDockerfileを書くことのほうが多いという印象を、調べていく中で、うけました。


ちなみに、複数のコンテナを使うときはDockerComposeを使う必要があります。

Docker Composeは、複数のコンテナで構成されるアプリケーションについて、Dockerイメージのビルドや各コンテナの起動・停止などをより簡単に行えるようにするツールです。
引用元:Docker入門(第六回)〜Docker Compose〜 | さくらのナレッジ

ブログチュートリアルでは、WebサーバとMySQLサーバの2つを使うので、DockerComposeを使う必要があります。

3 環境構築

それでは、環境構築をしていきます。
今回は、以下のサイトを参考に環境構築を進めていきます。
DockerでCakePHP2の開発環境を作ってみた(Mac版) – GeekGirl Cafe

3.1 CakePHP2リポジトリのクローン

まず任意のディレクトリに作業ディレクトリを作成し、CakePHP2をクローンします。

$ mkdir blog-turorial
$ git clone -b 2.x git://github.com/cakephp/cakephp.git blog-tutorial

さて、クローンしたばかりのCakePHPリポジトリですが、これは全世界の人が使うバニラな状態です。
例えば我々は日本人なのでタイムゾーンを東京にしたり、アプリの名前とかを設定したりというのは、個別でしなければなりません。後程使用するMySQLコンテナとの接続設定なども必要です。まずは、以下のサイトを参考にそういう設定をしていきます。

[CakePHP2]インストールの覚え書きです。 - Qiita

3.2 app/tmpのパーミッション修正

app/tmpのパーミッションを変える必要があります。
Apacheからのアクセスを可能にするためみたいです。
これについてはブログチュートリアル内でも説明があると思います。

blog-tutorial$ sudo chmod -R 777 app/tmp

3.3 タイムゾーン設定

タイムゾーンを設定する必要があります。東京にします。

blog-tutorial$ vi lib/Cake/Cache/CacheEngine.php
CacheEngine.php
        if (!is_numeric($this->settings['duration'])) {
            date_default_timezone_set('Asia/Tokyo'); //追加
            $this->settings['duration'] = strtotime($this->settings['duration']) - time();
        }

3.4 データベース設定

データベースの設定を行います。
普通はdatabase.phpはdatabase.php.defaultをコピーしてそれを参考に書きますが今回は新規作成でOKです。

blog-tutorial$ vi app/Config/database.php
database.php
class DATABASE_CONFIG {

    public $default = array(
        'datasource' => 'Database/Mysql',
        'persistent' => false,
        'host' => 'db',
        'login' => 'root',
        'password' => 'root_password',
        'database' => 'blog_tutorial',
        'prefix' => '',
        'encoding' => 'utf8',
    );

}

3.5 Security.saltの設定

Security.saltの設定をします。
これもブログチュートリアル内で説明がありますね。

blog-tutorial$ vi app/Config/core.php
core.php
/**
 * A random string used in security hashing methods.
 */
    Configure::write('Security.salt', 'pl345e-P45s_7h3*S@l7!'); //ランダムで長い文字列に変更

/**
 * A random numeric string (digits only) used to encrypt/decrypt strings.
 */
    Configure::write('Security.cipherSeed', '7485712659625147843639846751'); //ランダムで長い数字列に変更

3.6 DebugKitをインストール

DebugKitをインストールし、bootstrap.phpに読み込ませます。

blog-tutorial$ mkdir app/Config/Plugin/DebugKit
blog-tutorial$ git clone https://github.com/cakephp/debug_kit -b 2.2 app/Config/Plugin/DebugKit
blog-tutorial$ vi app/Config/bootstrap.php
bootstrap.php
//コメントアウトを解除
CakePlugin::load('DebugKit');

AppController.phpにも追加で記述します。

blog-tutorial$ vi app/Controller/AppController.php
AppController.php
class AppController extends Controller {
    public $components = array('DebugKit.Toolbar'); //追加
}

3.7 Dockerfileの作成

Dockerfileを作成します。

3.7.1 Dockerfile-apacheの作成

まずはApacheコンテナ用のDockerfileを作成します。

blog-tutorial$ mkdir docker
blog-tutorial$ vi docker/Dockerfile-apache
Dockerfile-apache
FROM php:5.6-apache

RUN apt-get update -yqq \
  && apt-get install -yqq --no-install-recommends \
  git \
  zip \
  unzip \
  && rm -rf /var/lib/apt/lists

# Enable PHP extensions
RUN docker-php-ext-install pdo_mysql mysqli

# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer

# Add cake and composer command to system path
ENV PATH="${PATH}:/var/www/html/lib/Cake/Console"
ENV PATH="${PATH}:/var/www/html/app/Vendor/bin"

# COPY apache site.conf file
COPY ./docker/apache/site.conf /etc/apache2/sites-available/000-default.conf

# Copy the source code into /var/www/html/ inside the image
COPY . .

# Set default working directory
WORKDIR ./app

# Create tmp directory and make it writable by the web server
RUN mkdir -p \
  tmp/cache/models \
  tmp/cache/persistent \
  && chown -R :www-data \
  tmp \
  && chmod -R 770 \
  tmp

# Enable Apache modules and restart
RUN a2enmod rewrite \
  && service apache2 restart

EXPOSE 80

3.7.2 Dockerfile-MySQLの作成

参考サイトではMySQLイメージは既存のものを使用していますが、それで作成したMySQLコンテナでは日本語が使えなかったので、こちらもDockerfileから作成していきます。

参考:DockerのMySQLコンテナを日本語対応させる - Qiita

blog-tutorial$ vi docker/Dockerfile-MySQL
Dockerfile-MySQL
FROM mysql:5.7

RUN apt-get update
RUN apt-get -y install locales-all

ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8

COPY ./docker/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf

3.8 Apache site.confの作成

dockerディレクトリにapahceディレクトリを作成し、site.confを作成します。

blog-tutorial$ mkdir docker/apache
blog-tutorial$ vi docker/apache/site.conf
site.conf
<VirtualHost *:80>
    DocumentRoot /var/www/html/app/webroot/

    <Directory /var/www/html/app/webroot/>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

3.9 mysqld_charset.cnfの作成

dockerディレクトリにmysqld_charset.cnfを作成します。

blog-tutorial$ vi docker/mysqld_charset.cnf
mysqld_charset.cnf
[mysqld]
character_set_server=utf8
character_set_filesystem=utf8
collation-server=utf8_general_ci
init-connect='SET NAMES utf8'
init_connect='SET collation_connection = utf8_general_ci'
skip-character-set-client-handshake

3.10 docker.compose.ymlの作成

docker.compose.ymlを作成します。
参考サイトではメールサーバーが立っていますが、ブログチュートリアルではいらないので、消します。

blog-tutorial$ vi docker-compose.yml
docker-compose.yml
version: "3"

services:
  app:
    build:
      context: .
      dockerfile: docker/Dockerfile-apache
    volumes:
      - .:/var/www/html
    ports:
      - 8000:80
    environment:
      TZ: "Asia/Tokyo"
    depends_on:
      - db

  db:
    build:
      context: .
      dockerfile: docker/Dockerfile-MySQL
    volumes:
      - db-data:/var/lib/mysql
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: blog_tutorial
      MYSQL_ROOT_PASSWORD: root_password
      TZ: "Asia/Tokyo"

volumes:
  db-data:
    external: false

3.11 ビルド&実行

設定が完了したので、Docker Composeのビルドと実行を行います。

blog-tutorial/docker$ docker-compose build

以下のような警告がいくつか出ますが無視でOKです。

Step 11/12 : RUN a2enmod rewrite   && service apache2 restart
 ---> Running in 38bfaf787e92
Enabling module rewrite.
To activate the new configuration, you need to run:
  service apache2 restart
Restarting Apache httpd web server: apache2AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
.
Removing intermediate container 38bfaf787e92
 ---> 342196dde2c3

気になるならビルド前に以下のサイトを参考にDockerfileを修正してください。

[Docker]AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using .... Set the 'ServerName' directive globally to suppress this message - Qiita

ビルドが終わったら実行しましょう。

blog-tutorial/docker$ docker-compose up

localhost:8000にアクセスします。

cakephp ok.PNG

上のほうにエラーが表示されていなく、文を囲む四角形が全部緑色だったらOKです!

4 終わりに

まだなんとなくしか理解できていませんが、それでもDockerは便利だなあと思ったので、今後Dockerを使わずに環境構築をすることはないのかなと思いました。

Twitterのフォローもお願いします!

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

Cloud9(Amazon Linux+Rails5.2+MySQL5.7)

1 現状のMySQLバージョンを確認

$ mysql --version

2 旧バージョン(5.5)パッケージ関連を削除

$ sudo yum -y remove mysql-config mysql55-server mysql55-libs mysql55

3 新バージョン(5.7)パッケージ関連をインストール

sudo yum -y install mysql57-server mysql57

4 日本語文字化け対策を実施

$ sed -e "/utf8/d" -e "/client/d" -e "/^\[mysqld_safe\]$/i character-set-server=utf8\n\n[client]\ndefault-character-set=utf8" /etc/my.cnf |sudo tee /etc/my.cnf

5 MySQL確認&起動

$ mysql --version
$ sudo service mysqld start

6 MySQL Account を作る

$ sudo mysql -u root   #rootユーザーでログイン
$ mysql> create user 'ユーザー名' identified by 'パスワード';  #ユーザー作成
$ mysql> grant all on *.* to 'ユーザー名';  #ALL権限付与

#作成したユーザーの確認は下記コマンド
$ mysql> select User,Host from mysql.user;

7 順番にライブラリをインストール&mysql2(gem)のインストール

$ sudo yum install mysql57-devel
$ sudo yum -y install ruby-devel
$ sudo yum groupinstall "Development Tools"

$ gem install mysql2

8 Railsをインストール

$ gem install rails -v 5.2.1

9 プロジェクトを作成

$ rails new projectname --database=mysql

10 config/database.ymlの編集

default: &default
  adapter: mysql2
  encoding: unicode
  pool: 5
  # 以下、3行追加
  username: <username> # 設定したMySQL Accountと同一のもの
  password: <password> # 設定したMySQL Accountと同一のもの
  host: localhost

development:
  <<: *default
  database: appname_development # appnameのところは、rails new時のappnameになっているはずです。
test:
  <<: *default
  database: appname_test # appnameのところは、rails new時のappnameになっているはずです。

11 rails db:createでデータベースを作成

$ cd appname
$ rails db:create

#rails5の場合は不要
$ source <(curl -sL https://cdn.learnenough.com/yarn_install)
$ yarn install --check-files
$ rails webpacker:install

#config/enviroments/development.rb
config.hosts.clear
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CakePHP4 のクエリビルダで実装されていないMySQL関数はマジックメソッドでそのまま実行される

[MySQL][CakePHP4] GROUP_CONCAT でカラム値を連結したい&group_concat_max_len システム変数
の続きです。

結論

  • 2020年11月29日時点で CakePHP4 には GROUP_CONCAT 関数は実装されていない
  • マジックメソッドによりMySQL の関数を直接実行するので group_concat と書けば動く
  • postgreSQL, SQL Server, SQLite に対し、機能追加の PR が出ているがまだマージされていない
  • よって、MySQL 以外はまだ使えない
  • マージされたら RDBMS の種類関係なくキャメルケースの groupConcat として使える

GROUP_CONCAT の PR

@ktouさんが調べてくださった CakePHP4 の GROUP_CONCAT の PR を読んでいて、なるほど MySQL はおそらくそのまま関数を実行していて、他のRDBMS では実行できないから PR 出されているんだな、と理解はしてたのですが、実際のコードと動きから実証したわけではありませんでした。
が、なんと引き続き調べてくださっていました。圧倒的感謝…
よって流れをまとめさせていただきます。

僕も疑問だったんですが、軽く CakePHP4 本体のコードを追っていたら、CakePHP4 自体に存在しない関数はそのまま MySQL の関数を呼んでそう…と予測するところで考えるのをやめてしまってました。

そうしたら、なんと引き続きコードを追ってくださっていて…なんかもう僕がコードを追わせてしまった感じになっていて申し訳ない限りなのですが、これはもう感謝しかないということで Qiita に投稿している次第です。TL に埋もれさせてはいかん。

該当のコードを引用します。

    /**
     * Magic method dispatcher to create custom SQL function calls
     *
     * @param string $name the SQL function name to construct
     * @param array $args list with up to 3 arguments, first one being an array with
     * parameters for the SQL function, the second one a list of types to bind to those
     * params, and the third one the return type of the function
     * @return \Cake\Database\Expression\FunctionExpression
     */
    public function __call(string $name, array $args): FunctionExpression
    {
        return new FunctionExpression($name, ...$args);
    }

なるほど…CakePHP4 にない関数が呼ばれた場合はマジックメソッドで処理されるんですね。そしてたまたま group_concat とスネークケースで書いていたので、MySQL と同じ関数だったので実行できていた、ということでした。

また、PR がマージされたら、 groupConcat とキャメルケースで呼び出すのが正しい実装となると思います。

今後

上記の PR がマージされたら、改めて動作検証した結果を反映します。

感謝

Twitterで軽い気持ちでわからないことを呟いたら、あれよあれよと言う間にすごい人たちがリプをくださり、検証してくださって、本当に感謝しかないです。
僕にとって、Twitterって世界はほんといつもいい刺激とインプットがもらえる最高の場所だし、最高な人がたくさんいて最高だなって語彙を失うレベルで日々みています。

僕も最高だなって思ってもらえるよう今後も活動していかねばって思わせていただいてます。
本当にいつも感謝です!ありがとうございますm(__)m

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

環境構築 さくっとまとめ(vagrant・CentOS7・rails・mysql8.0)

◇記事の概要

こちらの記事は、環境構築する際にドキュメントを探しにいくのが面倒なので、個人的な備忘録として残したものです。
※必要最低限の設定

その1: Vagrantfileの設定

※vagrant及びvirtualboxがインストールされている前提とします。
まずは、ターミナルを開く。
vagrantfileを置きたいフォルダで以下のコマンドを叩く

$ vagrant init centos/7

フォルダ上にvagrantfileが作成される。
その「Vagrantfile」を修正します。
修正内容は必要最低限の内容になります。

vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.network "private_network", ip: "192.168.33.10"
end

その2:vagrantの起動

vagrantを起動して、ssh接続します。

$ vagrant up

起動後、、

$ vagrant ssh

これで、こんな感じのターミナルが表示される

[vagrant@localhost ~]$

これで一旦vagrant上の作業環境ができた。

その3:rubyのインストール関連

必要なパッケージをインストールする。

[vagrant@localhost ~]$ sudo yum install -y git gcc openssl-devel readline-devel zlib-devel sqlite-devel gcc-c++ libicu-devel cmake vim

次に、rbenvをインストールします。環境変数を追加し、「source ~/.bash_profile」で内容を反映させます。

[vagrant@localhost ~]$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv    
[vagrant@localhost ~]$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
[vagrant@localhost ~]$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
[vagrant@localhost ~]$ source ~/.bash_profile

rbenv --versionと打って、バージョンが表示されれば、OK!

次に、「ruby-build」というプラグインをインストールします。
これは、rbenv installコマンドを使用するために必要なので、下記コマンドを入力します。

こちらの記事より
http://ruby.studio-kingdom.com/rbenv/ruby_build/

[vagrant@localhost ~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

次に、rubyをインストールします。
注意:個人的な都合で、こちらのバージョンを指定しています。

[vagrant@localhost ~]$ rbenv install 2.6.3
[vagrant@localhost ~]$ rbenv global 2.6.3
[vagrant@localhost ~]$ rbenv rehash

ruby -vと打って、バージョンが表示されれば、OK!

最後に、gem同士の互換性を補完するなど、gemを管理してくれる「bundler」をインストールします。

[vagrant@localhost ~]$ gem install bundler
[vagrant@localhost ~]$ rbenv rehash

bundle -v と打って、バージョンが表示されれば、OK!

その4:git clone作業(必要な場合のみ)

今回は、sshを使用して既存のコードをクローンしてきました。

[vagrant@localhost ~]$ cd ~/.ssh
[vagrant@localhost ~]$ ssh-keygen -t rsa
[vagrant@localhost ~]$ sudo cat id_rsa.pub

これで公開鍵・秘密鍵ができます。
公開鍵をgit(今回はbitbucket)に登録し、クローンしました!

その5:Mysql8.0の導入

ここからmysql8.0を使えるようにしていきます。

[vagrant@localhost ~]$ sudo yum install mysql80-community-release-el7-{version-number}.noarch.rpm
[vagrant@localhost ~]$ sudo yum install mysql-community-server
[vagrant@localhost ~]$ sudo systemctl start mysqld
[vagrant@localhost ~]$ sudo grep 'temporary password' /var/log/mysqld.log // 一時的に設定されているパスワードを確認
[vagrant@localhost ~]$ mysql -uroot -p //上記で確認したパスワードを使用
[mysql]$ ALTER USER 'root'@'localhost' IDENTIFIED BY 'ここに新パスワード'; //パスワード変更
[mysql]$ quit;
// bundle installするとmysql関連でエラー出るので、それを回避するために以下のプラグイン等をインストールする
[vagrant@localhost ~]$ sudo yum install mysql-devel 
[vagrant@localhost ~]$ gem install mysql2 -v '0.4.10' --source 'https://rubygems.org/' // ここはクローンしてきたgemに含まれていなかったので。。。
[vagrant@localhost ~]$ bundle install

◇参考
Mysql公式
HARU-LABO

mysqlを使用できるようになるまであと少し。
何が足りないかというと、「database.yml」の設定です。
設定しないと、「rails s」してアクセスするとエラーが出るはず!
参考までに設定ファイル載せておきます。
ファイル設置場所は、app名/config/database.yml

database.yml
default: &default
  adapter: mysql2
  pool: 5
  username: root
  password: 設定したパスワード
  encoding: utf8mb4
  charset: utf8mb4
  collation: utf8mb4_general_ci
  host: localhost

development:
  <<: *default
  database: 開発用DB名

test:
  <<: *default
  database: テスト用DB名
  username: テスト用ユーザー名
  password: テスト用パスワード

production:
  <<: *default
  database: 本番用DB名
  username: 本番用ユーザー名
  password: 本番用パスワード

database.ymlを設定し下記コマンドを入力すると、「database.yml」で設定したdatabaseが作成される。

[vagrant@localhost app名]$ rails db:create

テスト用・本番用は必要に応じて設定。

その6:「rails s」を起動

bundle installもうまくいくはずなので、rails sを行ったところ、以下のエラーが発生。
※一部抜粋

Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)

というエラー内容。
Javascriptを実行するために必要なプログラムが必要とのこと。
解決策としては、
①「mini_racer」のgemをインストール
②「Node.js」をインストール
前の環境ではNode.jsを利用していたので、②の手順を示します。

// 投稿時点のバージョン
[vagrant@localhost ~]$ curl -sL https://rpm.nodesource.com/setup_15.x | sudo bash -
[vagrant@localhost ~]$ sudo yum install -y nodejs

これで、rails sも実行可能に。

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

Embulkを利用してデータの引っ越しをしてみよう

はじめに

Ateam Brides Inc. Advent Calendar 2020の2日目は
株式会社エイチームブライズ サイト開発部 20卒エンジニアの@takaHALが担当します!

やること

image.png
こういうデータが何百、何千とある場合に
データの転送を楽にサクッと行いたい!!

csvとmysql間の転送を公式のクイックスタートを元に試します。

Embulk とは

image.png

様々なストレージ、DB、NoSQL、クラウドサービス間のデータ転送をサポートしてくれるオープンソースのETL(Extract/Transform/Load)ツール

豊富なプラグインを使用することで様々なデータ転送を実現することができます。

  • csv → mysql
  • mysql → BigQuery
  • SalesForce → BigQuery
  • mysql → Elasticsearch

などのデータが転送可能です。

Embulk(エンバルク)プラグインのまとめ

image.png
引用: Embulk, an open-source plugin-based parallel bulk data loader

Embulkドキュメント
https://github.com/embulk/embulk

セットアップ

公式のクイックスタートを見ながらセットアップします。

$ curl --create-dirs -o ~/.embulk/bin/embulk -L "https://dl.embulk.org/embulk-latest.jar"
$ chmod +x ~/.embulk/bin/embulk
$ echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc

サンプルを動かしてみる

$ embulk example ./try1
$ embulk guess ./try1/seed.yml -o config.yml
  • 作成されたサンプル

スクリーンショット 2020-11-29 14.23.43.png

config.yml
in:
  type: file
  path_prefix: ./try1/csv/sample_
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: LF
    type: csv
    delimiter: ','
    quote: '"'
    escape: '"'
    null_string: 'NULL'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
out: {type: stdout}

config.ymlをみてみましょう embulkの書き方としては

  • in (データを取得する部分)
  • out (データを出力する部分)

の二つをそれぞれオプションを記載していくことで inで取ってきたものを → outで指定したところへのデータ転送を行います

in:
  type: file
  path_prefix: ./try1/csv/sample_
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: LF
    type: csv
    delimiter: ','
    quote: '"'
    escape: '"'
    null_string: 'NULL'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
out: {type: stdout}
$ embulk preview config.yml
  • embulk preview config.yml

embulk previewコマンドを利用することでどんなデータが転送されるかを事前にチェックすることができます。

+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                            |
+---------+--------------+-------------------------+-------------------------+----------------------------+

サンプルのcsv

image.png

previewで問題なさそうなら実行するという流れになります。

このままだとUTCの時間なのでタイムゾーンを変更してみます

parserの部分にdefault_timezone: 'Asia/Tokyo'を追加します

config.yml
parser:
  default_timezone: 'Asia/Tokyo'
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       1 |       32,864 | 2015-01-27 10:23:49 UTC | 2015-01-26 15:00:00 UTC |                     embulk |
|       2 |       14,824 | 2015-01-27 10:01:23 UTC | 2015-01-26 15:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-27 17:20:02 UTC | 2015-01-27 15:00:00 UTC | Embulk "csv" parser plugin |
|       4 |       11,270 | 2015-01-29 02:54:36 UTC | 2015-01-28 15:00:00 UTC |                            |
+---------+--------------+-------------------------+-------------------------+----------------------------+
$ embulk run config.yml
  • embulk run config.yml

preview で確認した情報が出力できました。

1,32864,2015-01-27 10:23:49,20150126,embulk
2,14824,2015-01-27 10:01:23,20150126,embulk jruby
3,27559,2015-01-27 17:20:02,20150127,Embulk "csv" parser plugin
4,11270,2015-01-29 02:54:36,20150128,

サンプルを改造して様々なデータ転送を試してみましょう

csv ⇄ mysqlの場合

利用するプラグイン

CSVはサンプルで取得したcsvをそのまま使います

csv → mysql

プラグインをインストール

$ embulk gem install embulk-output-mysql
config.yml
in:
  type: file
  path_prefix: ./try1/csv/sample_
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: LF
    type: csv
    delimiter: ','
    quote: '"'
    escape: '"'
    null_string: 'NULL'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    default_timezone: 'Asia/Tokyo'
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
out:
  type: mysql
  host: localhost
  user: root
  password: ""
  database: my_database
  table: my_table
  mode: insert

modeを指定することで単純なinsertやテーブル置換、upsertなどに対応できます。

DBの用意

とりあえず元のcsvに合わせる感じでざっくりと作成

mysql> CREATE DATABASE my_database;
mysql> USE my_database;
mysql> CREATE TABLE my_database.my_table (
    -> id INTEGER,
    -> account INTEGER,
    -> time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    -> purchase DATETIME DEFAULT CURRENT_TIMESTAMP,
    -> comment varchar(255)
    -> );

実行

$ embulk preview config.yml
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       1 |       32,864 | 2015-01-27 10:23:49 UTC | 2015-01-26 15:00:00 UTC |                     embulk |
|       2 |       14,824 | 2015-01-27 10:01:23 UTC | 2015-01-26 15:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-27 17:20:02 UTC | 2015-01-27 15:00:00 UTC | Embulk "csv" parser plugin |
|       4 |       11,270 | 2015-01-29 02:54:36 UTC | 2015-01-28 15:00:00 UTC |                            |
+---------+--------------+-------------------------+-------------------------+----------------------------+
$ embulk run config.yml

データの確認

mysql> select * from my_database.my_table;
+------+---------+---------------------+---------------------+----------------------------+
| id   | account | time                | purchase            | comment                    |
+------+---------+---------------------+---------------------+----------------------------+
|    1 |   32864 | 2015-01-27 19:23:49 | 2015-01-27 00:00:00 | embulk                     |
|    2 |   14824 | 2015-01-27 19:01:23 | 2015-01-27 00:00:00 | embulk jruby               |
|    3 |   27559 | 2015-01-28 02:20:02 | 2015-01-28 00:00:00 | Embulk "csv" parser plugin |
|    4 |   11270 | 2015-01-29 11:54:36 | 2015-01-29 00:00:00 | NULL                       |
+------+---------+---------------------+---------------------+----------------------------+

mysql → csv

csv → mysql の際に利用したテーブルをそのまま利用します。

プラグインをインストール

$ embulk gem install embulk-input-mysql
config.yml
in:
  type: mysql
  host: localhost
  user: root
  password: ""
  database: my_database
  table: my_table
  select: "id, account, time, purchase, comment"
  where: "comment <> 'embulk'"
out:
  type: file
  path_prefix: ./try1/csv/sample
  sequence_format: "."
  file_ext: csv
  formatter:
    type: csv
    delimiter: ","
    newline: CRLF
    newline_in_field: LF
    charset: UTF-8
    quote: '"'

config.ymlのinの部分で以下のデータが取得できます。

mysql> SELECT id, account, time, purchase, comment
    -> FROM my_database.my_table
    -> WHERE comment <> 'embulk';
+------+---------+---------------------+---------------------+----------------------------+
| id   | account | time                | purchase            | comment                    |
+------+---------+---------------------+---------------------+----------------------------+
|    2 |   14824 | 2015-01-27 19:01:23 | 2015-01-27 00:00:00 | embulk jruby               |
|    3 |   27559 | 2015-01-28 02:20:02 | 2015-01-28 00:00:00 | Embulk "csv" parser plugin |
+------+---------+---------------------+---------------------+----------------------------+

実行

$ embulk preview config.yml
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
+---------+--------------+-------------------------+-------------------------+----------------------------+
$ embulk run config.yml

データの確認

sample.csv
id,account,time,purchase,comment
2,14824,2015-01-27 19:01:23.000000 +0000,2015-01-27 00:00:00.000000 +0000,embulk jruby
3,27559,2015-01-28 02:20:02.000000 +0000,2015-01-28 00:00:00.000000 +0000,"Embulk ""csv"" parser plugin"

mysql → csvへの出力も確認できました。

やってみて感じたこと

mysql → BigQuery
SalesForce → BigQuery
mysql → SalesForce

csv、mysql以外にも試してみてみたのでembulkについて感じたことを書きます

  • ポジティブ

    • いろんなデータを並列で転送できる便利なやつ
    • プラグインを入れるのが楽
    • 条件抽出することが可能
    • 抽出したものをそのまま転送するだけではなく、フィルターを通すことでデータを加工してから転送することもできる
    • embulkを活用し、いろんなデータを集約することでデータ分析が捗りそう
  • ネガティブ

    • プラグインの最終コミットが古いので利用するプラグインによっては、使い勝手が悪い場合などモヤモヤしたり、バグを見つけた際に困りそう
    • embulkで使える型と、送る先の型などで微妙に慣れないうちは直感的ではなくフィルタープラグインで少し加工しないといけない場合があったSalesForceなど

総合的にデータ連携の基盤を作ってる感があり楽しい?

他にもETLはたくさんあるので色々試してみようと思ってます

オススメのものがあればコメントで教えてください

直近だと
Embulk + Argoの組み合わせも面白そうなので今度試す予定です。

最後に

Ateam Brides Inc. Advent Calendar 2020の3日目は、
@oekazumaがお送りします!!どんなネタを用意してくるのか楽しみです!!

参考にさせていただいた記事

Embulk(エンバルク)組み込みプラグインの設定覚え書き
大量データの転送にEmbulkを使ってみたら本当に楽だった
Embulkを使って、RDSのデータをBigQueryへロード

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

MySQL dumpファイルを出力する

目的

  • MySQLのdumpファイルの出力方法をまとめる

前提情報

  • 特定のDBのdumpファイルを出力する。

詳細

  • 下記を実行するとカレントディレクトリに「出力されるdumpファイル名」のファイルが出力される。MySQLのユーザパスワードの入力を求められたら入力する。※出力されるdumpファイル名は拡張子も指定する。

    mysqldump --single-transaction -u DBユーザ名 -p DB名 > 出力されるdumpファイル名
    
  • --single-transactionのオプションは「このオプションは、サーバーからデータをダンプする前に BEGIN SQL ステートメントを発行」らしい。言うなればdumpファイルを出力するときに処理がトランザクションで囲まれる。

参考文献

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

【Cloud9】MySQLの起動・接続・db作成・確認・選択まで。

MySQLの起動方法

$ sudo service mysqld start

MySQLのステータス確認

$ sudo service mysqld status

データベースサーバへの接続

$ mysql -u root

データベースの作成(サーバへの接続後)

mysql> CREATE DATABASE bookstore;

bookstoreデータベースが作成される。

データベースの確認(サーバへの接続後)

mysql> SHOW databases;

データベースの選択(サーバへの接続後)

mysql> USE bookstore;

bookstoreデータベースを選択して、操作可能にする。

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