誰でもできるGCP ~ローカル環境から各種データ更新メソッドを実行~

#はじめに
Google Cloud Platform(以降GCP)って色々できるみたいだけど、まずは何をどう動かしていけば良いのか？ を知るため、まずは基本的な操作をしてみようと思いました。そんなクラウド初心者が公式ドキュメントを参照し、ローカル環境のプログラムからGCPを動かしてみた過程を記録しました。

今回はStorageとBigQueryを扱いましたが、同じ要領でText APIやVision APIなど他の各種Cloud API(*)を実行することができました。
( * https://cloud.google.com/apis/)

前提

- GCPのアカウント(プロジェクト)を有効化済み
- ローカル環境からプログラムを実行する
- 仮想環境、オブジェクト指向などはここでは考えない.
- Windows(コマンドプロンプト),Pythonで実行する(ただし他環境・言語でも手順は同じ。コード/コマンドは公式ドキュメントの関連項目に記載がある)

# 目次
- Google Cloud Strageの動かし方
    - ライブラリをインストールする
    - アプリケーションの認証を行う
        - サービス アカウントキーを作成する
        - サービスアカウントキーのパスを環境変数で指定する
    - プログラムでクライアントライブラリを利用する
        - サンプル1: Google Cloud Strageのバケットを作る
        - サンプル2: Google Cloud Strageのバケット一覧を取得する
- BigQueryの動かし方
    - ライブラリをインストールする
    - アプリケーションの認証を行う
        - サービス アカウントキーを作成する
        - サービスアカウントキーのパスを環境変数で指定する
    - プログラムでクライアントライブラリを利用する
        - サンプル1: パブリックなDBからデータを取得する
        - サンプル2: プライベートなDBにデータを追加する
        - サンプル3: プライベートDBからデータを取得する
        - サンプルその他
            - テーブル一覧化&全て削除する
            - テーブル作成&データ追加する

# Google Cloud Strageの動かし方
目標：Google Cloud Strageでデータの保存と取得を行う
## ライブラリをインストールする
Google Cloud Strageを操作するためには、GCPのAPIクライアントを利用する必要がある。そのために、Googleから提供されているクライアントライブラリ「google-cloud-storage」をインストールしておく。

- ローカル環境にライブラリをインストールする
 
```
(実行)
$pip install --upgrade google-cloud-storage

(結果)
Successfully installed google-cloud-storage-X.XX.X
```


▽公式ドキュメント
その他環境については下記公式ドキュメント(Installing the client library)を参照。
https://cloud.google.com/storage/docs/reference/libraries?hl=ja#client-libraries-install-python


##アプリケーションの認証を行う
### サービス アカウントキーを作成する
自分のクラウド環境に接続するためには、セキュリティ保護のため認証情報を設定する必要がある（ただし既にそのアカウントのjsonキーを発行している場合、jsonキー発行はせず、そのアカウントにbigqueryの権限付与のみ行う）。


- 認証情報を取得するため、下記公式ドキュメントから、[サービス アカウントキーの作成]ボタンをクリックし、アカウントキー作成画面に移動する
https://cloud.google.com/storage/docs/reference/libraries?hl=ja#setting_up_authentication

- 上記操作にてサービスアカウントの管理者に「ストレージ」の権限を付与し、jsonキーを発行する

###サービスアカウントキーのパスを環境変数で指定する
プログラムファイル実行時、クラウド環境に接続するための認証情報を読み込む必要がある。そのためにパスの設定を行う。

- サービスアカウントキー=jsonキーのファイルを任意のディレクトリに設置する
- そのパス＋ファイル名を下記コマンドで環境変数に設定する                 

```
$set GOOGLE_APPLICATION_CREDENTIALS=C:\Users\...\<project_name>.json
```
 
▽公式ドキュメント
その他環境については下記公式ドキュメント(Setting up authentication)を参照。
https://cloud.google.com/storage/docs/reference/libraries?hl=ja#setting_up_authentication

##プログラムでクライアントライブラリを利用する
### サンプル1: Google Cloud Strageのバケットを作る
- 下記公式ドキュメントから「quickstart.py」をコピーする

  https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/storage/cloud-client/quickstart.py

- ファイルを実行する

```
(実行)
$py quickstart.py

(結果)
-> Bucket my-new-bucket created.
```
→新しいバケット「my-new-bucket」ができた。

### サンプル2: Google Cloud Strageのバケット一覧を取得する

- 下記公式ドキュメントのコードを利用してファイルを作る

 https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/storage/cloud-client/snippets.py
（= https://cloud.google.com/python/?hl=ja に記載のソースコード）

```list_buckets.py
#クライアントライブラリのインポート
from google.cloud import storage
storage_client = storage.Client()
#認証済のAPIリクエスト
buckets = storage_client.list_buckets()
for bucket in buckets:
    print(bucket.name)
```

- ファイルを実行する

```
(実行)
$py snippets.py

(結果)
my-new-bucket
```
→作成済バケット一覧が表示された

▽公式ドキュメント
その他環境については下記公式ドキュメント(GoogleCloudPlatformの他サンプルファイル)を参照。
https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/storage/cloud-client/quickstart.py


# BigQueryの動かし方
目標：BigQueryでデータの保存と取得を行う
## ライブラリをインストールする
BigQueryを操作するためには、GCPのAPIクライアントを利用する必要がある。そのために、Googleから提供されているクライアントライブラリ「google-cloud-bigquery」をインストールしておく。

- ローカル環境にライブラリをインストールする

``` 
(実行)
$pip install --upgrade google-cloud-bigquery

(結果)
Successfully installed google-cloud-bigqury-X.XX.X
```


▽公式ドキュメント
その他環境については下記公式ドキュメント(Installing the client library)を参照。
https://cloud.google.com/bigquery/docs/reference/libraries?hl=ja#client-libraries-install-python


##アプリケーションの認証を行う
### サービス アカウントキーを作成する
自分のクラウド環境に接続するためには、セキュリティ保護のため認証情報を設定する必要がある（ただし既にそのアカウントのjsonキーを発行している場合、jsonキー発行はせず、そのアカウントにbigqueryの権限付与のみ行う）。

- 認証情報を取得するため、下記公式ドキュメントから、[サービス アカウントキーの作成]ボタンをクリックし、アカウントキー作成画面に移動する
https://cloud.google.com/bigquery/docs/reference/libraries?hl=ja#setting_up_authentication

- 上記操作にてサービスアカウントの管理者に「ビッグクエリー」の権限を付与し、jsonキーを発行する

###サービスアカウントキーのパスを環境変数で指定する
プログラムファイル実行時、クラウド環境に接続するための認証情報を読み込む必要がある。そのためにパスの設定を行う（ただし既にそのjsonキーのパスを設定している場合、このステップは不要）。

- サービスアカウントキー=jsonキーのファイルを任意のディレクトリに設置する
- そのパス＋ファイル名を下記コマンドで環境変数に設定する                 

```
$set GOOGLE_APPLICATION_CREDENTIALS=C:\Users\...\<project_name>.json
```
 
▽公式ドキュメント
その他環境については下記公式ドキュメント(Setting up authentication)を参照。
https://cloud.google.com/bigquery/docs/reference/libraries?hl=ja#setting_up_authentication

##プログラムでクライアントライブラリを利用する
### サンプル1: パブリックなDBからデータを取得する
- 下記公式ドキュメントから「simple_app.py」をコピーする

  https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/bigquery/cloud-client/simple_app.py

- ファイルを実行する

```
(実行)
$py simple_app.py

(結果)
https://stackoverflow.com/questions/22879669 : 52306 views
https://stackoverflow.com/questions/13530967 : 46073 views
https://stackoverflow.com/questions/35159967 : 45991 views
https://stackoverflow.com/questions/10604135 : 45238 views
https://stackoverflow.com/questions/16609219 : 37758 views
https://stackoverflow.com/questions/11647201 : 32963 views
https://stackoverflow.com/questions/13221978 : 32507 views
https://stackoverflow.com/questions/27060396 : 31630 views
https://stackoverflow.com/questions/6607552 : 31487 views
https://stackoverflow.com/questions/11057219 : 29069 views
```

→新しいバケット「my-new-bucket」ができた。


### サンプル2: プライベートDBにデータを追加する
- 
-下記公式ドキュメントのコードを利用してファイルを作る

https://github.com/googleapis/google-cloud-python/blob/cf04f6d15615b09c1de9e584bb3462653f0770f1/bigquery/docs/snippets.py
(= https://cloud.google.com/bigquery/docs/tables#creating_a_table_from_a_query_result に記載のソースコード)
(= https://googleapis.dev/python/bigquery/latest/usage/queries.html#writing-query-results-to-a-destination-table にも記載がある)


```test_api_post.py
#クライアントライブラリのインポート
from google.cloud import bigquery
client = bigquery.Client()
dataset_id = 'emata'

job_config = bigquery.QueryJobConfig()
# Set the destination table
table_ref = client.dataset(dataset_id).table("test_api_post")
job_config.destination = table_ref
sql = """
    SELECT corpus
    FROM `bigquery-public-data.samples.shakespeare`
    GROUP BY corpus;
"""

# Start the query, passing in the extra configuration.
query_job = client.query(
    sql,
    # Location must match that of the dataset(s) referenced in the query
    # and of the destination table.
    location="US",
    job_config=job_config,
)  # API request - starts the query

query_job.result()  # Waits for the query to finish
print("Query results loaded to table {}".format(table_ref.path))

```

- ファイルを実行する

```
(実行)
$py test_api_post.py

(結果)
Query results loaded to table /projects/my-api-project/datasets/emata/tables/test_api_post
```
→BigQueryのテーブルにデータが追加された
![table_preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521810/f30b21bb-7502-3ea5-a256-3c6ac562bea0.png)


※備考
後ほど記載するデータ取得を行うコードと比較すると分かる通り、"job_config"をパラメータ設定するところが、データ取得を行うコードと異なる。このコードでは、client.query=(sql=..., ..., job_config=...) 内のパラメータとして 以下job_configで出力先の設定をすることで書き込みを行う。

```
job_config = bigquery.QueryJobConfig()
table_ref = client.dataset(dataset_id).table("test_api_post")
job_config.destination = table_ref
```



### サンプル3: プライベートDBからデータを取得する

- 下記公式ドキュメントのコードを利用してファイルを作る

https://github.com/googleapis/google-cloud-python/blob/7ba0220ff9d0d68241baa863b3152c34dc9f7a1a/bigquery/docs/snippets.py
（https://cloud.google.com/bigquery/docs/reference/libraries?hl=ja#client-libraries-usage-python に記載のソースコード）

→"query = ("の中のクエリ文とlocationは自分のテーブルに合わせて書き変える


```snippets.py
#クライアントライブラリのインポート
from google.cloud import bigquery
client = bigquery.Client()

query = (
    "SELECT * FROM `my-project.emata.test_api_post` "
    "LIMIT 10"
)
query_job = client.query(
    query,
    location="US",
) 

for row in query_job:  # API request - fetches results
    print(row)

```

- ファイルを実行する

```
(実行)
$py snippets.py

(結果)
Row(('2kinghenryvi',), {'corpus': 0})
Row(('kinglear',), {'corpus': 0})
Row(('1kinghenryiv',), {'corpus': 0})
Row(('tempest',), {'corpus': 0})
Row(('comedyoferrors',), {'corpus': 0})
Row(('kingjohn',), {'corpus': 0})
Row(('rapeoflucrece',), {'corpus': 0})
Row(('1kinghenryvi',), {'corpus': 0})
Row(('kingrichardiii',), {'corpus': 0})
Row(('othello',), {'corpus': 0})
```
→登録済データ一覧が表示された


▽公式ドキュメント
その他環境については下記公式ドキュメント(GoogleCloudPlatformの他サンプルファイル)を参照。
https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/storage/cloud-client/quickstart.py

### サンプルその他
####テーブル一覧化&全て削除する
```
from google.cloud import bigquery
client = bigquery.Client()
dataset_id = 'dataset_name'
tables = client.list_tables(dataset_id)
print("Tables contained in '{}':".format(dataset_id))
for table in tables:
    client.delete_table(table, not_found_ok=True)
    print("Deleted table '{}'.".format(table))
```
▽公式ドキュメント
Getting a Table & Deleting a Table
https://googleapis.dev/python/bigquery/latest/usage/tables.html#deleting-a-table

####テーブル作成&データ追加する
```
from google.cloud import bigquery
# TODO(developer): Construct a BigQuery client object.
client = bigquery.Client()
# TODO(developer): Set table_id to the ID of the table to create
#table_id = "your-project.your_dataset.your_table_name"
table_id = "my-api-project-167306.emata.create_and_update_table_api"
schema = [
    bigquery.SchemaField("full_name", "STRING", mode="REQUIRED"),
    bigquery.SchemaField("age", "INTEGER", mode="REQUIRED"),
]
table = bigquery.Table(table_id, schema=schema)
table = client.create_table(table)  # API request
print(
    "Created table {}.{}.{}".format(table.project, table.dataset_id, table.table_id)
)
rows_to_insert = [(u"Phred Phlyntstone", 32), (u"Wylma Phlyntstone", 29)]
errors = client.insert_rows(table, rows_to_insert)  # API request
assert errors == []
```
▽公式ドキュメント
Creating a Table & Updating a Table
https://cloud.google.com/bigquery/docs/tables#creating_an_empty_table_with_a_schema_definition
https://cloud.google.com/bigquery/docs/tables#creating_a_table_from_a_query_result
(= https://googleapis.dev/python/bigquery/latest/usage/tables.html#updating-a-table)


---
何かあればお手数ですが、本記事か以下アカウントでお知らせください！

**\ *Follow Me!* /**
**[*Qiitaアカウント*](https://qiita.com/MasatoEmata)**
**[*Twitterアカウント*](https://twitter.com/masatoemata)**