この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、みかみです。
BigQuery にデータをロードする場合、データファイルのエンコーディングは UTF-8(または ISO-8859-1 )がサポートされています。
Shift-JIS(SJIS)ファイルだとロードできないのでしょうか?
やりたいこと
- BigQuery に SJIS ファイルをロードした場合の挙動を確認したい
- BigQuery に SJIS ファイルをロードするにはどうすればいいか知りたい
SJIS ファイルデータをそのままロードしてみる
以下の SJIS の CSV ファイルを準備しました。
col_num,col_alp,col_jp,col_timestamp
12345678,abcdefgh,日本語カタカナ,2021-06-15 00:00:00
99999999,ABCDEFGH,にほんごカタカナ,2021/06/15 23:59:59
file
コマンドでも、エンコーディングが SJIS であることが確認できます。
mikami_yuki@cloudshell:~/sample/sjis (cm-da-mikami-yuki-258308)$ file sample_sjis.csv
sample_sjis.csv: Non-ISO extended-ASCII text
ためしに bq load
コマンドで、SJIS のファイルをそのままロードしてみます。
mikami_yuki@cloudshell:~/sample/sjis (cm-da-mikami-yuki-258308)$ bq load --autodetect \
> --source_format=CSV \
> dataset_1.table_sjis \
> ./sample_sjis.csv
Upload complete.
Waiting on bqjob_r3b4bebe58e0f35d4_0000017a0e32a660_1 ... (1s) Current status: DONE
エラーにはならず、半角英数などのシングルバイト文字は正常にロードできましたが、マルチバイト文字の日本語は文字化けしてしまいました。。
mikami_yuki@cloudshell:~/sample/sjis (cm-da-mikami-yuki-258308)$ bq query "select col_jp from dataset_1.table_sjis"
Waiting on bqjob_r1b68b5b5432748a_0000017a0e374f00_1 ... (0s) Current status: DONE
+----------------+
| col_jp |
+----------------+
| ��–{��ƒJƒ^ƒJƒi |
| �ɂق?��Å |
+----------------+
シェルスクリプトで UTF-8 に変換してからロード
以下の bash スクリプトを準備しました。
#!/bin/bash
iconv -f sjis -t utf8 sample_sjis.csv > sample_utf8.csv
bq load --autodetect --source_format=CSV dataset_1.table_utf8 ./sample_utf8.csv
bq query "select col_jp from dataset_1.table_utf8" > result_table_utf8.txt
iconv
コマンドで UTF-8 に変換した新しいファイルを作成し、作成した UTF-8 のファイルを BigQuery にロードします。
ロード後には結果を確認するため、SJIS のファイルで文字化けしていた日本語カラムのデータを select してファイルに出力してみます。
mikami_yuki@cloudshell:~/sample/sjis (cm-da-mikami-yuki-258308)$ bash ./load_utf8.sh
Upload complete.
Waiting on bqjob_r45bd90bb2121d699_0000017a0e3e55f2_1 ... (1s) Current status: DONE
Waiting on bqjob_r7d034edc5790cb41_0000017a0e3e66a2_1 ... (0s) Current status: DONE
ロード結果の出力ファイルを確認すると
+----------------+
| col_jp |
+----------------+
| 日本語カタカナ |
| にほんごカタカナ |
+----------------+
問題なくロードできているようです。
念のため、BigQuery のテーブルデータも確認してみます。
マルチバイト文字(日本語)も文字化けすることなくテーブルに格納することができました。
pandas DataFrame に読み込んでからロード
ファイルのエンコーディング変換なしで、python プログラムでファイルデータを一度 pandas Dataframeに読み込んでから BigQuery にロードすることもできます。
以下の python コードを実行してみます。
import pandas as pd
file_path = './sample_sjis.csv'
df = pd.read_csv(file_path, encoding='shift-jis')
print(df)
dataset_id = 'dataset_1'
table_id = 'table_python'
df.to_gbq('{}.{}'.format(dataset_id, table_id), if_exists='replace')
mikami_yuki@cloudshell:~/sample/sjis (cm-da-mikami-yuki-258308)$ python3 load_sjis.py
col_num col_alp col_jp col_timestamp
0 12345678 abcdefgh 日本語カタカナ 2021-06-15 00:00:00
1 99999999 ABCDEFGH にほんごカタカナ 2021/06/15 23:59:59
ファイルデータが文字化けせずにロードできたか、BigQuery のテーブルデータを確認してみます。
テーブルスキーマを指定しなかったので日時項目も STRING 型で格納されましたが、マルチバイト文字でも文字化けすることなく、正常にロードすることができました。
まとめ(所感)
BigQuery でサポートされていない SJIS ファイルのデータをロードしてもエラーにはなりませんが、日本語などのマルチバイト文字は文字化けしてしまいます。
ロードファイルを初めから UTF-8 で出力できればベストですが、SJIS ファイルのデータでも、シェルスクリプトや python コードで簡単にロードできました。
SJISファイルをロードする場合、ロード前にエンコーディングを UTF-8 に変換してしまうのも良いですが、ロード時にカラムの追加やデータフォーマット変換などの整形処理を行いたい場合は、pandas の DataFrame を使えば、そのまま BigQuery にロードできるので便利です。
なお、本エントリでは pandas.DataFrame
の to_gbq
を使用しましたが、google-cloud-bigquery
ライブラリにも DataFrame を BigQuery にロードするインターフェースがあるので、あわせてご確認ください。