仮想サーファーの波乗り

仮想化エンジニアの日常

プログラミング・SNS分析・仮想通貨・自動化などに関してよく書く雑記ブログ

PythonでSlackBot開発⑥「MySQL連携してデータベース利用」


PythonでSlackBotを開発しよう企画の第6回目。今回はデータの保存・加工をしていくために、MySQL(データベース)に連携していきます。データベース連携することで、ツイート情報の保存をしたり、保存しておいたデータを加工して利用することができるので、アプリケーション開発には必須です。

f:id:virtual-surfer:20180407144305p:plain

前回までの第5回目まででは、↑ のように、Pythonアプリケーションで受け取ったデータはそのまま出力することしかできないという構成だったのが...


f:id:virtual-surfer:20180407144422p:plain

今回で ↑ のような構成になり、APIアクセスしてPythonアプリケーションで取得したデータを保存し、更新処理をして出力できるようにしていきます!

データベース連携ができればTwitterAPIなどのAPIにはアクセス上限があるのが普通なので、APIアクセス回数を最低限に抑えるためにも、一度取得したデータは保存しておきたいですし。DB連携させとくのマジ大事。Python入門書をパラパラ立ち読みしてみたのですが、意外にもデータベース連携の話を扱ってる本少ない印象でした。「アプリケーション開発入門」と言いながら、ライブラリ使ってちょっとした機能体験して終わり・・・。みたいなことで終わってしまっては、実際に使われるようなアプリケーションを開発する能力は伸びないと思うのでアプリケーションのデータベース連携させていきます。


MySQLのインストールと初期設定

今回は、Homebrewを利用してインストールしていきます。まずはterminalで以下のコマンドを打ち込んでMySQLをインストールしていきます。

$ brew install mysql


HomebrewでMySQLインストールすることができたら、MySQLを起動して、ログインしてパスワードの初期設定などを進めていきましょう。

まずはMySQLサーバーを起動します。

$ mysql.server start

... SUCCESS!


ルート権限のユーザーでログインします。まだパスワードを設定していないので、パスワードを指定しなくてもログイン出来ます。

$ mysql -u root

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.21 Homebrew

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>


以下のように、「xxx」の箇所を自分の設定したいパスワードに書き換えて、パスワードの設定をしておきます。

mysql> SET PASSWORD FOR root@localhost=PASSWORD('xxx');

Query OK, 0 rows affected, 1 warning (0.00 sec)

これでパスワードの設定をすることができました。「$ mysql -u root -p」コマンドを打ち込んだのち、パスワードを入力することでログインすることができるようになると思います。

$ mysql -u root -p
Enter password: 

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.21 Homebrew

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>


ついでにユーザー名も「root」から変更しておきましょう。以下のコマンドで「root」→「xxx」に変更します。

mysql> rename user 'root'@'localhost' to 'xxx'@'loclahost';

Query OK, 0 rows affected (0.01 sec)


これで、以下のコマンドでログインすることができるようになりました。

$ mysql -u xxx -p
Enter password: 

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.21 Homebrew

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>


MySQLでDB/テーブル作成・登録

MySQLにログインすることができるようになったので、Databaseを作成して、テーブルを作成していきましょう。

mysql> create database test;

Query OK, 1 row affected (0.01 sec)

f:id:virtual-surfer:20180407151451p:plain

これで「test」という名前のデータベースを作成することができました。

以下のコマンドでデータベースを確認すると、「test」という名前のデータベースが作成できていることを確認できます。

mysql> show databases;

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test   |
+--------------------+
5 rows in set (0.00 sec)


次に、「$ use test」というコマンドで、「test」というデータベースに入ります。

mysql> use test

Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed


次にデータベース内に「twitter_user」という名前のテーブルを作成していきます。以下のコマンドでテーブルとカラム内容のテーブルを作成していきます。

mysql> CREATE TABLE twitter_user
    ->   (twitter_user_id int AUTO_INCREMENT COMMENT 'ツイッターユーザーID',
    ->    user_name varchar(255) NOT NULL COMMENT 'ユーザー名',
    ->    user_screen_name varchar(255) NOT NULL COMMENT 'アカウント名',
    ->    profile_image_link varchar(255) NOT NULL COMMENT 'プロフィール画像',
    ->    ins_datetime datetime NOT NULL COMMENT '作成日時',
    ->    upd_datetime datetime NOT NULL COMMENT '更新日時',
    ->    INDEX(twitter_user_id),
    ->    PRIMARY KEY (twitter_user_id)) ENGINE=InnoDB CHARSET=utf8 COMMENT='ツイッターユーザー';

Query OK, 0 rows affected (0.02 sec)

また、「twitter_tweet」という名前のテーブルも作成しておきます。

mysql> CREATE TABLE twitter_tweet
    ->   (tweet_id int AUTO_INCREMENT COMMENT 'ツイートID',
    ->    user_id int NOT NULL COMMENT 'ツイッターユーザーID',
    ->    twitter_tweet_id int NOT NULL COMMENT 'ツイッターツイートID',
    ->    tweet_text varchar(255) NOT NULL COMMENT 'ツイート本文',
    ->    tweet_datetime datetime NOT NULL COMMENT 'ツイート日時',
    ->    ins_datetime datetime NOT NULL COMMENT '作成日時',
    ->    upd_datetime datetime NOT NULL COMMENT '更新日時',
    ->    INDEX(tweet_id),
    ->    PRIMARY KEY (tweet_id)) ENGINE=InnoDB CHARSET=utf8 COMMENT='ツイッターツイート';

Query OK, 0 rows affected (0.03 sec)


ここまでで、「test」データベース内に「twitter_tweet」と「twitter_user」テーブルを作成することができました。

f:id:virtual-surfer:20180407152027p:plain

以下のコマンドで「twitter_user」テーブルの中身を見てみると、登録できていることが確認できます。

mysql> describe twitter_user;

+--------------------+--------------+------+-----+---------+----------------+
| Field              | Type         | Null | Key | Default | Extra          |
+--------------------+--------------+------+-----+---------+----------------+
| twitter_user_id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_name          | varchar(255) | NO   |     | NULL    |                |
| user_screen_name   | varchar(255) | NO   |     | NULL    |                |
| profile_image_link | varchar(255) | NO   |     | NULL    |                |
| ins_datetime       | datetime     | NO   |     | NULL    |                |
| upd_datetime       | datetime     | NO   |     | NULL    |                |
+--------------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

以下のコマンドで登録されているテーブルを確認することができます。

mysql> show tables;

+----------------------------+
| Tables_in_virtualsurferbot |
+----------------------------+
| twitter_tweet              |
| twitter_user               |
+----------------------------+
2 rows in set (0.00 sec)


テーブルにレコード(データ)を登録していきましょう。以下のクエリを発行します。

mysql> INSERT INTO twitter_user (user_name, user_screen_name, profile_image_link, ins_datetime, upd_datetime) VALUES ('仮想サーファー@webエンジニア', 'virtual_techX', '952006494731431936/oERsC_dh_400x400.jpg', '2018-04-07 14:10:21', '2018-04-07 14:10:21');

Query OK, 1 row affected (0.01 sec)

「twitter_user」テーブルの中身を確認すると、登録できていることが確認できます。

mysql> mysql> select * from twitter_user;

+-----------------+------------------------------------------+------------------+-----------------------------------------+---------------------+---------------------+
| twitter_user_id | user_name                                | user_screen_name | profile_image_link                      | ins_datetime        | upd_datetime        |
+-----------------+------------------------------------------+------------------+-----------------------------------------+---------------------+---------------------+
|               1 | 仮想サーファー@webエンジニア             | virtual_techX    | 952006494731431936/oERsC_dh_400x400.jpg | 2018-04-07 14:10:21 | 2018-04-07 14:10:21 |
+-----------------+------------------------------------------+------------------+-----------------------------------------+---------------------+---------------------+
1 row in set (0.00 sec)


以上で、データベースとテーブルの用意をすることができました。あとは自分のアプリケーションで利用するテーブルを作成しておきます。


Heroku上でもMySQL用意

ここまででLocal(自分の手元のPC)環境でのMySQLを用意することができましたが、Heroku上にデプロイしたアプリケーションでもMySQLを利用できるようにしておきましょう。

HerokuでMySQL機能アドオンのため、「$ heroku addons:create cleardb:ignite」というコマンドを実行。

$ heroku addons:create cleardb:ignite

Creating cleardb:ignite on ⬢ xxx... !
 ▸    Please verify your account to install this add-on plan (please enter a credit card) For more information, see https://devcenter.heroku.com/categories/billing Verify now at
 ▸    https://heroku.com/verify

「クレジットカードを登録してください」という表示が。仕方ないので登録しますか。


Heroku

f:id:virtual-surfer:20180407155457p:plain

クレジットカード登録画面を確認すると、「クレジットカード登録してくれたら無料利用枠の上限 1000h/1month になるよ!」という表示が。とりあえずクレジットカード登録してもらいたいんでしょうね。

クレジットカード情報の登録を行って再度挑戦!

$ heroku addons:create cleardb:ignite

Creating cleardb:ignite on ⬢ xxx... free
Created cleardb-adjacent-xxx as CLEARDB_DATABASE_URL
Use heroku addons:docs cleardb to view documentation

今回は無事アドオンすることができました。


「$ heroku config | grep CLEARDB_DATABASE_URL」コマンドで、設定できた「CLEARDB_DATABASE_URL」の値を確認します。

$ heroku config | grep CLEARDB_DATABASE_URL

CLEARDB_DATABASE_URL: mysql://xxxxx?reconnect=true

登録されている「xxxxx?reconnect=true」を利用して、「$ heroku config:set DATABASE_URL='mysql2://xxxxx?reconnect=true'」コマンドでDATABASE_URLの値を設定しておきます。(xxxxxの部分は各自の環境によって異なっているので、書き換えてください。)

$ heroku config:set DATABASE_URL='mysql2://xxxxx?reconnect=true'

Setting DATABASE_URL and restarting ⬢ xxx... done, v109
DATABASE_URL: mysql2://xxxxx?reconnect=true'

これで「DATABASE_URL」の値が設定できたはずです。以下の「$ heroku config | grep DATA」コマンドで確認すると、登録することができていることを確認できます。

$ heroku config | grep DATA

CLEARDB_DATABASE_URL: mysql://xxxxx?reconnect=true'
DATABASE_URL: mysql2://xxxxx?reconnect=true'


長くなってきたので、今回はここまで!!

実際にデータベースを作成しながらこの記事を書いたのですが、途中なぜか(パスワード設定コピペミスってた?のか)MySQLにログインできなくなって、やむなく「$ brew uninstall mysql」でMySQLをアンインストールして再度インストールするという事態になって無駄に時間を使って消耗してしまいました...。


次回はSQLAlchemyというO/Rマッパーを利用して、DB(MySQL)に対してSQLを発行してデータのやり取りをしていきます。

ちなみに、今回ググりながらMySQL連携に試みて非効率に感じ、「入門書を参考にしよう!」と思ってPython入門書を20冊くらいパラ見しました。結果として、Pythonアプリケーションでのデータベース連携の話は『15時間でわかる Python集中講座』が一番わかりやすいなあと思いました。超初心者で右も左も分からないです!という人は読んでみてもいいかも。


では!