Google Cloud のインポート API を使用して、Google Cloud Storage の CSV ファイルを Cloud SQL MySQL 5.7 データベースに読み込みます。
https://cloud.google.com/sql/docs/mysql/admin-api/v1beta4/instances/import
インポート API は、「utf8」文字セットを想定する MySQL データベースへの LOAD DATA INFILE コマンドを生成します。ただし、私の CSV ファイルのデータは、「utf8」のスーパーセットである「utf8mb4」エンコーディングを使用しています。これにより、一部の文字列を 'utf8' にエンコードできない場合、ロード プロセスが失敗します。
Exception: CloudSQL Exception: {'kind': 'sql#operation', 'selfLink': 'https://www.googleapis.com/sql/v1beta4/projects/***', 'targetProject': '***', 'targetId': '***', 'targetLink': 'https://www.googleapis.com/sql/v1beta4/projects/***', 'name': '0211c99e-0633-42f1-9ee1-069473308273', 'operationType': 'IMPORT', 'status': 'RUNNING', 'user': '***', 'insertTime': '2019-01-14T02:36:39.861Z', 'startTime': '2019-01-14T02:36:39.972Z', 'error': {'kind': 'sql#operationErrors', 'errors': [{'kind': 'sql#operationError', 'code': 'ERROR_RDBMS', 'message': "Import CSV error: Error 1300: Invalid utf8 character string: ''Afikanisitani|'Apekanikana|A Phu Han (Afghanistan)|A Phú Hãn '\n"}]}, 'importContext': {'kind': 'sql#importContext', 'uri': '***', 'database': '**', 'importUser': '', 'csvImportOptions': {'table': '***'}}}
関連記事: "'message': "Import CSV error: Error 1300: Invalid utf8 character string:"
インポート API (またはその他の文字セット) を使用して 'utf8mb4' CHARACTER SET を追加する方法はありますか?
'csvImportOptions' ディクショナリに 'character set': 'utf8mb4' を追加して実験してみましたが、インポート API はその dict で 'table' および 'columns' キーのみを想定しているようです。
MySQL クライアントから LOAD DATA INFILE コマンドを直接実行すると、問題なく CSV をインポートできることに注意してください。
LOAD DATA INFILE 'myCSVFile.csv'
INTO TABLE 'my table'
CHARACTER SET utf8mb4
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 ROWS
from pprint import pprint
from googleapiclient import discovery
from oauth2client.client import GoogleCredentials
credentials = GoogleCredentials.get_application_default()
service = discovery.build('sqladmin', 'v1beta4', credentials=credentials)
# Project ID of the project that contains the instance.
project = 'my-project' # TODO: Update placeholder value.
# Cloud SQL instance ID. This does not include the project ID.
instance = 'my-instance' # TODO: Update placeholder value.
instances_import_request_body = {
"importContext": {
"kind": "sql#importContext",
"fileType": "CSV",
"uri": gcs_uri,
"database": database,
"csvImportOptions": {
"table": table
}
}
}
request = service.instances().import_(project=project, instance=instance, body=instances_import_request_body)
response = request.execute()
追加データ ポイント Google の API が生成している LOAD DATA INFILE クエリがデフォルトで 'utf8' 文字セットになっていることは明らかです。
API と同じエラー メッセージで失敗する
LOAD DATA INFILE 'problematic.csv'
INTO TABLE my_table
**CHARACTER SET utf8**
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '\"'
ESCAPED BY '\"'
ERROR 1300 (HY000): Invalid utf8 character string: ''Afikanisitani|'Apekanikana|A Phu Han (Afghanistan)|A Phú Hãn '
作品:
LOAD DATA INFILE 'problematic.csv'
INTO TABLE my_table
**CHARACTER SET utf8mb4**
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '\"'
ESCAPED BY '\"'
Query OK, 75641 rows affected (1.14 sec)
Records: 75641 Deleted: 0 Skipped: 0 Warnings: 0
ここのドキュメントは正しくありません: https://cloud.google.com/sql/docs/mysql/import-export/importing
LOAD DATA INFILE ... ***CHARACTER SET 'utf8mb4'***
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '\"'.