Pythonで、MySQL5.7のJSON型にツイートを保存してみる

Python独学ならTech-Joho TOP > いろいろやってみた > Pythonで、MySQL5.7のJSON型にツイートを保存してみる

取得したツイートを保存したい

前回、ツイッターから特定のキーワードで検索したツイートを取得するPythonプログラムをつくりました。

Twitterで特定のフレーズで検索して結果を表示する

このままだと、検索したツイートは目でみて確認するだけで終わりで、あとで分析することもできません。ツイートを保存する仕組みが必要です。

MySQLのJSON型を使ってみたい

保存するにはデータベースを使います。しかし、データベースを言ってもいろいろな候補があります。

候補1: MongoDB

取得できるツイートはJSON形式で、リツイートの具合などによって構造は微妙に変わります。こういうときはNoSQLで、MongoDBが最初に思い浮かびました。

ただ、MongoDBは、あまりたくさんのデータを保存するのに向いていないところがあります。やたら容量をくって、えらい目にあった経験があり、余り使いたくありません。

他にもCouchDB、Cassandraなんかもちょっと考えましたが、よく知らないのと調べるのが面倒くさかったのでやめました。

参考

候補2: MySQL

しっかりと、列の構造を決めて、ふつうにMySQLに保存するというのも考えました。しかし、モデルを作るのがめんどくさくてやめました。

JSON型

そこで思い出したのですが、MySQLの列のデータ型で、JSON型というのがあります。

単に一つの文字列型の列にJSON文字列を突っ込むように使えますが、検索などの際、JSONのキーで検索できるようです。

一度使ってみたかったのでこれにします。

MySQL5.6の後半から使えるようになったみたいです。

参考

https://www.webprofessional.jp/use-json-data-fields-mysql-databases/
https://www.s-style.co.jp/blog/2017/06/420/

CRATE文

こうなりました。

CREATE TABLE `tweets` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` json NOT NULL,
  `created` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

datetime型でも、DEFAULT CURRENT_TIMESTAMPで作成時間を入れられるようになったみたいです。
http://dekokun.github.io/posts/2014-05-31.html

MySQLは5.7.21にしました。

Pythonのコード

こうなりました。

from twython import TwythonStreamer, TwythonError
import json
import config
import mysql.connector
import sys


conn = mysql.connector.connect(
    host='localhost',
    port=3306,
    user=config.MYSQL_USER,
    password=config.MYSQL_PASS,
    database='twitter_app'
)

if not conn.is_connected():
    print('could not connect to db')
    sys.exit()
conn.ping(reconnect=True)
cur = conn.cursor()


class MyStreamer(TwythonStreamer):
    def on_success(self, data):
        json_text = json.dumps(data)

        try:
            sql = "insert into tweets (content) values (%s);"
            cur.execute(sql, (json_text,))
            conn.commit()
        except Exception as err:
            conn.rollback()
            print('could not commit inserting:', json_text)
            print('error:', err)
        if 'text' in data:
            print(data['text'])

    def on_error(self, status_code, data):
        print(status_code)


try:
    stream = MyStreamer(config.APP_KEY, config.APP_SECRET, config.ACCESS_TOKEN, config.ACCESS_TOKEN_SECRET)
    stream.statuses.filter(track='AKB')

except TwythonError as e:
    print(e)

configモジュールに、MySQLのパスワードなどいろいろな定数を入れています。

使っているライブラリはmysql-connector-python-rfになりました。mysql-pythonにしようとしたら、変なエラーがでてインストールできませんでした。

$ pip install mysql-connector-python-rf
https://stackoverflow.com/questions/37092125/cant-install-mysql-python-version-1-2-5-in-windows

ツイートの本文だけ取り出す

SELECT
  id,
  content->"$.text" AS `text`
FROM sport_twitter_dev.tweets;

便利です。

Author: 管理

tech-joho.infoの管理人です。いろいろな技術について勉強しています。