アーキテクチャ図
ちなみにステップ数は約20ステップ。こんなの楽勝だと思ってたら何日もハマってしまった。
ソース
ソースも簡単。StackOverflowにあるまんま書けば良い。
def importDs(request):
import googleapiclient.discovery
from oauth2client.client import GoogleCredentials
credentials = GoogleCredentials.get_application_default()
service = googleapiclient.discovery.build('sqladmin', 'v1beta4', credentials=credentials)
# Project ID of the project that contains the instance.
project = '[プロジェクト名]' # TODO: Update placeholder value.
# Cloud SQL instance ID. This does not include the project ID.
instance = '[CloudSQLのインスタンス名]' # TODO: Update placeholder value.
instances_import_request_body = {
"importContext": {
"uri": "[GCSの場所]",
"database": '[database名]',
"fileType": "CSV",
"csvImportOptions": {
"table": "[テーブル名]"
}
}
}
request = service.instances().import_(project=project, instance=instance, body=instances_import_request_body)
response = request.execute()
google-api-python-client==1.9.3
google-auth-httplib2==0.0.3
google-auth==1.17.2
oauth2client==4.1.3
The service account does not have the required permissions for the bucket.にハマる。
参照するCloudStorageにあるCSVファイルが他のPJなので、Cloud Funtionの権限をCloudStorageにつけてもアクセスが出来ない。
え?なんで?普通これで動くんじゃないのか??PJすべてのサービスアカウントやIAMで定義されているものすべて付けても動かない。これで何日もハマる。
正解は、CloudSQLインスタンスのサービスアカウントをCloudStrageに付与
「CloudFuntionはCloudSQLのAPIからimportするから、CloudSQLインスタンスのサービスアカウントをCloudStrageに付与すれば動くんじゃないのか?」と思いついてやったら、アッサリ動きました。
ここのサービスアカウントをCloudStoregeのバケットに付与する。
CloudStorageの該当バケットの三点リーダーを押して、権限を追加します。
「項目を追加」から、
エンティティ: 「ユーザー」
名前 : CloudSQLインスタンスのサービスアカウント
アクセス権: 「読み取り」 (読み取りしか使わないため)
上記で追加する。
backetでやる場合
バケットの編集権限を付与します。
メンバーを追加します。
Storageオブジェクトを閲覧にして追加します。
わかってしまえば1日もかからない作業に何日もかかってしまった。
ちょっと気になる
oauth2clientはもうdescriptionなので、google-authを使う形に変えたほうがいい。
参考URL
参考1:Import GCS CSV into Cloud SQL from Cloud Function
参考2:Google Cloud ドキュメント Method: instances.import
参考3:Google Cloud ドキュメント Cloud SQL にデータをインポートする
参考4:Google Cloud ドキュメント Cloud Functions から Cloud SQL に接続する