Python で Google Cloud Storage と、BigQuery を使おうと思い、google-cloud-storage と、google-cloud-bigqueryインストールしました。

スクリプトを幾つか書いて動作確認している最中に幾つかエラーに遭遇しました。
登録対象のデータのカテゴリごとに手順をまとめているのですが、エラー関連は共通で起こることなので、この記事にまとめて記載します。


前提

以下の環境で動作確認は実施しています。

  • OS

    cat /etc/redhat-release 
    CentOS Linux release 7.5.1804 (Core) 
    

  • Python

    python3.6 -V
    Python 3.6.7
    


Google Cloud Storage

インストール後、スクリプトを動かす過程で発生したエラーと、対処方法についてまとめます。

インストール

python3 -m pip install --upgrade google-cloud-storage

---
Successfully installed google-api-core-1.3.0 google-cloud-core-0.28.1 google-cloud-storage-1.11.0 google-resumable-media-0.3.1 googleapis-common-protos-1.5.3 protobuf-3.6.1 requests-2.19.1

認証情報の設定不備でのエラー

認証情報の設定 を行わないと、以下のエラーが発生します。

google.auth.exceptions.DefaultCredentialsError: Could not automatically determine credentials. Please set GOOGLE_APPLICATION_CREDENTIALS or
explicitly create credential and re-run the application. For more
information, please see
これは BigQuery も同様です。
  File "/usr/local/lib/python3.6/site-packages/google/auth/_default.py", line 292, in default
    raise exceptions.DefaultCredentialsError(_HELP_MESSAGE)
google.auth.exceptions.DefaultCredentialsError: Could not automatically determine credentials. Please set GOOGLE_APPLICATION_CREDENTIALS or
explicitly create credential and re-run the application. For more
information, please see
https://developers.google.com/accounts/docs/application-default-credentials.
エラーメッセージ上に、また、以下ドキュメントにGOOGLE_APPLICATION_CREDENTIALS設定方法の記載があります。

Python スクリプトから以下のようにGOOGLE_APPLICATION_CREDENTIALS設定しました。

    import os
    os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = './client_credentials.json'
ドキュメントには、storage.Client.from_service_account_json使う記述があるのですが、Python スクリプト上から設定する場合はこの設定方法が妥当かもしれません。
    # Explicitly use service account credentials by specifying the private key
    # file.
    storage_client = storage.Client.from_service_account_json(
        'service_account.json')
Python スクリプトではなく、Bash から設定する場合は以下のように設定します。
export GOOGLE_APPLICATION_CREDENTIALS="/Users/xxxxxxxxxx/keys//client_credentials.json"

権限設定時のストレージの<wbr>レガシー バケット<wbr>書き込み付与する

Python スクリプトからのファイルアップロード時に以下のエラーが発生しました。

  File "/usr/local/lib/python3.6/site-packages/google/cloud/_http.py", line 293, in api_request
    raise exceptions.from_http_response(response)
google.api_core.exceptions.Forbidden: 403 GET https://www.googleapis.com/storage/v1/b/xxxxxxxxxxxxxxxxxxxxxx.appspot.com?projection=noAcl: xxxxxxxxxxxxxx@Xxxxxxxxxxxxx.iam.gserviceaccount.com does not have storage.buckets.get access to xxxxxxxxxxxxxxxxxxxxxxx.appspot.com.   

これは サービスアカウントに、ストレージの<wbr>レガシー バケット<wbr>書き込み権限がなかったのが原因でした。
ストレージの<wbr>オブジェクト作成者 権限は付与していたのですが、これではファイルのアップロードができませんでした。
ストレージの<wbr>オブジェクト作成者アップロードするための権限ではないのかもしれません。

その他の問題

上記の権限問題の切り分けのため、設定を編集している際、誤って GCS のルートフォルダの権限を全削除してしまいました。
全アカウントのオブジェクトの更新、参照権限がなくなってオペレーションができなくなってしまいました。

サポートに問い合わせしないのではとも思ったのですが、ログアウトして、再度アクセスするとログインユーザの権限は復活していました。
焦りました。


BigQuery

インストール後に、発生したエラー内容をまとめます。

インストール

python3 -m pip install --upgrade google-cloud-bigquery

----------
Installing collected packages: google-cloud-bigquery
Successfully installed google-cloud-bigquery-1.5.0
----------

データセットの指定文字列不備

データセット名の指定可能な文字列は半角英数字とアンダースコアです。それ以外の文字列を指定すると、Invalid dataset IDいうエラーが出力されました。

google.api_core.exceptions.BadRequest: 400 POST https://www.googleapis.com/bigquery/v2/projects/xxxxxxxxxxxx/jobs: Invalid dataset ID "xxxxxxxxx-xxxxxxxxxx". Dataset IDs must be alphanumeric (plus underscores) and must be at most 1024 characters long.

データセットが存在しない

指定文字列の形式はあっているが、データセットが存在しない場合は 404 エラーになります。

    return super(_AsyncJob, self).result(timeout=timeout)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/future/polling.py", line 120, in result
    raise self._exception
google.api_core.exceptions.NotFound: 404 Not found: Dataset xxxxxxxxx:table was not found in location US

テーブルにカラムがない

テーブルに指定したカラムがない場合は、404 エラーになります。

    raise exceptions.from_http_response(response)
google.api_core.exceptions.NotFound: 404 GET https://www.googleapis.com/bigquery/v2/projects/xxxxxxxxxxx/datasets/aaaa/tables/column_name: Not found: Table xxxxxxxxxxx:aaaa.column_name     

クレジットカードの登録を行っていない。

データセットの登録を試みた際、クレジットカードの登録を行っておらず、エラーになりました。

Billing has not been enabled for this project. Enable billing at https://console.cloud.google.com/billing
https://console.cloud.google.com/billing からクレジットカード情報を登録すると、データセットの登録ができるようになります。
このタイミングで、Firebase のプロジェクトも連動するのか Spark プラン から、Blaze プランへ変更されます。
若干課金怖いですが、現状この状態で様子を見ています。

テーブル名に、全角フィールド名称は作成できない。

CSV の ヘッダカラム名が全角の場合、全角文字は_変化されて登録されました。

フィールド名タイプモード
_______________STRINGNULLABLE
_________INTEGERNULLABLE
____________INTEGERNULLABLE
h1______INTEGERNULLABLE
h2______INTEGERNULLABLE
h3______INTEGERNULLABLE
h4______INTEGERNULLABLE
h5______INTEGERNULLABLE
h6______INTEGERNULLABLE
table______INTEGERNULLABLE
li______INTEGERNULLABLE
dt______INTEGERNULLABLE
img______INTEGERNULLABLE
a______INTEGERNULLABLE

フィールド名が違う CSV を更新アップロードするとエラーになる。

更新時のマッピング情報がわからないからだと思いますが、以下のエラーになります。
テーブルを削除して再作成しました。

  File "/usr/local/lib/python3.6/site-packages/google/api_core/future/polling.py", line 120, in result
    raise self._exception
google.api_core.exceptions.BadRequest: 400 Invalid schema update. Cannot add fields (field: fileName)


参考

以下、参考した記事になります。

BigQuery 関連

Google Cloud Platform の利用規約

経験のなく、相当な Try & Error になっていましたが、Python からの登録はなんとかできるようになりました。
以上です。

コメント