毎日テキストマイニング

180日間、毎日テキストマイニングをするブログです

2018/7/2【10日目】変数の中身をMySQLにINSERTする(utf8mb4の設定)

昨日、データベースにデータを入れられることができたので、今日はTwiiterのデータを入れていきたいとおもいます。

複数の変数を入れるサンプルコードはOracleの公式ページにありましたので、これを参考にします。

https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html

insert_stmt = (
  "INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
  "VALUES (%s, %s, %s, %s)"
)
data = (2, 'Jane', 'Doe', datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)

select_stmt = "SELECT * FROM employees WHERE emp_no = %(emp_no)s"
cursor.execute(select_stmt, { 'emp_no': 2 })

↓書き直したコード

sql =  (
    "INSERT INTO akb_test5 (name, tweet) "
     "VALUES (%s, %s)"
)
data = (name, name)
crsr.execute(sql, data)
 db.commit()

Tweetの内容に絵文字が入っているためデータを保存できなかったので、代わりに変数nameを保存します。 これで、MySQLの中は、

name tweet
48_asainanami   48_asainanami

となりました。

データが保存できる事が確認できたので、他の変数も入れていきます。 コードはこんな感じになりました。

for j in range(3):
    res = twitter.get(url, params = params)
    if res.status_code == 200:
        timeline = json.loads(res.text)

        # 各ツイートの内容を保存
        for i in range(len(timeline)):
            if i == len(timeline)-1:
                created_data = timeline[i]['created_at']
                name = timeline[i]["user"]["screen_name"]
                tweet = timeline[i]['text']
                count_tweets = timeline[i]["user"]["statuses_count"]
                count_follows = timeline[i]["user"]["friends_count"]
                count_followers = timeline[i]["user"]["followers_count"]
                count_favolites = timeline[i]["user"]["favourites_count"]
                count_lists = timeline[i]["user"]["listed_count"]
                users_favorites = timeline[i]["user"]["favourites_count"]
                retweet = timeline[i]["retweet_count"]
                favorite = timeline[i]["favorite_count"]
                params['max_id'] = timeline[i]['id']-1

            sql =  (
              "INSERT INTO akb_test5 (created_data, name, tweet, count_tweets, count_follows, count_followers, count_favolites, count_lists, users_favorites, retweet, favorite)"
              "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
            )

            data = (created_data, name, tweet, count_tweets, count_follows, count_followers, count_favolites, count_lists, users_favorites, retweet, favorite)
            crsr.execute(sql, data)
            db.commit()

crsr.close()

実行結果

mysql.connector.errors.DataError: 1292 (22007): Incorrect time value: 'Sun Jul 01 09:45:46 +0000 2018' for column 'created_data' at row 1

もちろん型が合わないというエラーが返ってきます。 データベースの型を一個一個修正していきます。

型の修正にはALTERコマンドを使えばいいらしいですね。書式は次のようです。

ALTER TABLE テーブル名前 MODIFY フィールドの名前 データ型;

最初のcreated_dataからやっていきます。こいつはdata型じゃないよ、というエラーを起こしています。日付型で合うのを探したのですが、どうやら合うのがないようですので、created_dataは文字列型で保存すること にします。

ALTER TABLE akb_test5 MODIFY created_data varchar(50);

どうやら成功したようです。 さっきのPythonのコードを実行してみます。

実行結果

mysql.connector.errors.DatabaseError: 1366 (HY000): Incorrect string value: '\xF0\x9F\x91\x97\xF0\x9F...' for column 'tweet' at row 1

created_dataからtweetに移ったようなので、created_dataは保存できるようになったようです。 tweetのエラーは絵文字が対応していないとのことでした。設定していますutf8をutf8mb4に変更します。

utf8mb4に変更するには次のコマンドのようです。

SET character_set_database=utf8mb4;

実行と確認です。

SET character_set_database=utf8mb4;
show variables like 'character%’;

これでcharacter_set_databaseがtf8mb4;になりました。再びPythonコード実行。

mysql.connector.errors.DatabaseError: 1366 (HY000): Incorrect string value: '\xF0\x9F\x91\x97\xF0\x9F...' for column 'tweet' at row 1

エラー内容が変わらずでした。 いろいろやってみましたが解決できなかったのでデータベースを作り直してみました。

create database akb_tweet_test2 default character set utf8mb4;
use akb_tweet_test2;
create table tweet2(
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
created_data varchar(50) NOT NULL,
name varchar(50) NOT NULL,
tweet varchar(255) UNIQUE NOT NULL,
count_tweets int,
count_follows int,
count_followers int,
count_favolites int,
count_lists int, 
users_favorites int,
retweet int,
favorite int,
datesp DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

これでもエラー内容は変わらず。。。 ALTERコマンドを使って、カラム単位での変更もできるようなので、これを試してみます。

ALTER DATABASE akb_tweet_test CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;

これでもエラーは修正できず。。。

show variables like '%char%';

このコマンドで文字コードを確認すると、どうやら

character_set_client | utf8

これがutf8mb4になっておらず。。。いろいろ試してみましたが、結局うまくいったのはPython側から文字コードを指定してあげる事でした。以下、完成コードです。

for j in range(3):
    res = twitter.get(url, params = params)
    if res.status_code == 200:
        timeline = json.loads(res.text)

        # 各ツイートの本文を表示
        for i in range(len(timeline)):
            if i == len(timeline)-1:
                created_data = timeline[i]['created_at']
                name = timeline[i]["user"]["screen_name"]
                tweet = timeline[i]['text']
                count_tweets = timeline[i]["user"]["statuses_count"]
                count_follows = timeline[i]["user"]["friends_count"]
                count_followers = timeline[i]["user"]["followers_count"]
                count_favolites = timeline[i]["user"]["favourites_count"]
                count_lists = timeline[i]["user"]["listed_count"]
                users_favorites = timeline[i]["user"]["favourites_count"]
                retweet = timeline[i]["retweet_count"]
                favorite = timeline[i]["favorite_count"]
                params['max_id'] = timeline[i]['id']-1

            sql =  (
              "INSERT INTO tweet (created_data, name, tweet, count_tweets, count_follows, count_followers, count_favolites, count_lists, users_favorites, retweet, favorite)"
              "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
            )

            data = (created_data, name, tweet, count_tweets, count_follows, count_followers, count_favolites, count_lists, users_favorites, retweet, favorite)
            crsr.execute('SET NAMES utf8mb4')
            crsr.execute("SET CHARACTER SET utf8mb4")
            crsr.execute("SET character_set_connection=utf8mb4")
            crsr.execute(sql, data)
            db.commit()

crsr.close()

これでひとまずデータベースに保存することができました。 いろいろ検索してこのデータベースの使い心地を確かめたいと思います。

今日の結果

今日は最小の26件でした。これといった特徴もありませんでした。 f:id:rimt:20180703002506p:plain

形容詞 '楽しい': 3, 'ない': 2, '多い': 1, 'よい': 1, '切ない': 1, '恥ずかしい': 1, '可愛い': 1, '嬉しい': 1, '面白い': 1, 'すごい': 1, 'いい': 1, 'よろしい': 1, 'すっごい': 1

名詞 'ちゃん': 8, '今日': 7, '公演': 5, '人': 5, '中': 4, '目': 4, '出演': 4, '楽しい': 3, '時': 3, '背景': 3, 'の': 3, 'こと': 3, '感動': 3,

動詞 'する': 16, '見る': 9, 'ちゃん': 8, '今日': 7, '公演': 5, '人': 5, 'てる': 5, '中': 4, '目': 4, '出演': 4, '思う': 4, 'せる': 4, '楽しい': 3, '時': 3, '背景': 3, 'の': 3, 'こと': 3, '感動': 3, '来る': 3, 'くれる': 3, 'なる': 3, '変える': 3, 'すぎる': 3, 'くる': 3, '頂く': 3

今日勉強した事

  • 変数をデータベースへ保存する仕方
  • 文字コードの変更