web-dev-qa-db-ja.com

Bigquery-python)によって新しいデータ行をテーブルに挿入します

Google bigquery-pythonに関する多くのドキュメントを読みましたが、pythonコードでbigqueryデータを管理する方法がわかりません。

まず、以下のように新しいテーブルを作成します。

credentials = GoogleCredentials.get_application_default()
service = build('bigquery', 'v2', credentials = credentials)

project_id = 'my_project'
dataset_id = 'my_dataset'
table_id = 'my_table'

project_ref = {'projectId': project_id}
dataset_ref = {'datasetId': dataset_id,
               'projectId': project_id}
table_ref = {'tableId': table_id,
             'datasetId': dataset_id,
             'projectId': project_id}

dataset = {'datasetReference': dataset_ref}
table = {'tableReference': table_ref}
table['schema'] = {'fields': [
    {'name': 'id', 'type': 'string'},
...
]}

table = service.tables().insert(body = table, **dataset_ref).execute()

そして、このテーブルにデータを挿入したいので、以下のようにしようとしました。

fetch_list = []
patch = {'key': 'value'}
fetch_list.append(patch)

table = service.tables().patch(body = fetch_list, **table_ref).execute()

しかし、何も起こりませんでした。

新しいデータをbigqueryテーブルに更新するにはどうすればよいですか?

サンプルコードをいくつか見せてください。

5
Luis Kang

2018年11月編集:

この質問の答えは、グーグルクラウドクライアントがこの最後の投稿以来かなり進化しているため、すでに時代遅れです。

公式ドキュメントには、すでに必要なすべての情報が含まれています。 ここ ストリーミング挿入に必要なすべてのものを見つけることができます これ これまでに利用可能なすべてのメソッドの完全な概要があります(Pythonコードもあります各ページと各メソッドの例)。

元の回答:

BQにデータを挿入するために使用できるいくつかの異なる方法があります。

Python-apiがどのように機能するかをより深く理解するために、必要なものはすべてここにあります: bq-python-api (最初はドキュメントが少し怖いですが、コツをつかんだ後はかなりかなりですシンプル)。

BQにデータを挿入するために使用する主な方法は2つあります。最初のものは データストリーミング であり、リアルタイムで行ごとに挿入できる場合に使用されることになっています。コード例:

import uuid
def stream_data(self, table, data, schema):
    # first checks if table already exists. If it doesn't, then create it
    r = self.service.tables().list(projectId=your_project_id,
                                     datasetId=your_dataset_id).execute()
    table_exists = [row['tableReference']['tableId'] for row in
                    r['tables'] if
                    row['tableReference']['tableId'] == table]
    if not table_exists:
        body = {
            'tableReference': {
                'tableId': table,
                'projectId': your_project_id,
                'datasetId': your_dataset_id
            },
            'schema': schema
        }
        self.service.tables().insert(projectId=your_project_id,
                                     datasetId=your_dataset_id,
                                     body=body).execute()

    # with table created, now we can stream the data
    # to do so we'll use the tabledata().insertall() function.
    body = {
        'rows': [
            {
                'json': data,
                'insertId': str(uuid.uuid4())
            }
        ]
    }
    self.service.tabledata().insertAll(projectId=your_project_id),
                                       datasetId=your_dataset_id,
                                       tableId=table,
                                         body=body).execute(num_retries=5)

ここで、私のself.serviceはあなたのserviceオブジェクトに対応しています。

プロジェクトにある入力dataの例:

data = {u'days_validated': '20', u'days_trained': '80', u'navigated_score': '1', u'description': 'First trial of top seller alg. No filter nor any condition is applied. Skus not present in train count as rank=0.5', u'init_cv_date': '2016-03-06', u'metric': 'rank', u'unix_date': '1461610020241117', u'purchased_score': '10', u'result': '0.32677139316724546', u'date': '2016-04-25', u'carted_score': '3', u'end_cv_date': '2016-03-25'}

そしてその対応するschema

schema = {u'fields': [{u'type': u'STRING', u'name': u'date', u'mode': u'NULLABLE'}, {u'type': u'INTEGER', u'name': u'unix_date', u'mode': u'NULLABLE'}, {u'type': u'STRING', u'name': u'init_cv_date', u'mode': u'NULLABLE'}, {u'type': u'STRING', u'name': u'end_cv_date', u'mode': u'NULLABLE'}, {u'type': u'INTEGER', u'name': u'days_trained', u'mode': u'NULLABLE'}, {u'type': u'INTEGER', u'name': u'days_validated', u'mode': u'NULLABLE'}, {u'type': u'INTEGER', u'name': u'navigated_score', u'mode': u'NULLABLE'}, {u'type': u'INTEGER', u'name': u'carted_score', u'mode': u'NULLABLE'}, {u'type': u'INTEGER', u'name': u'purchased_score', u'mode': u'NULLABLE'}, {u'type': u'STRING', u'name': u'description', u'mode': u'NULLABLE'}, {u'type': u'STRING', u'name': u'metric', u'mode': u'NULLABLE'}, {u'type': u'FLOAT', u'name': u'result', u'mode': u'NULLABLE'}]}

データを挿入するもう1つの方法は、 job insert 関数を使用することです。ドキュメントでわかるように、データのいくつかのソースを受け入れます。クエリの結果を別のテーブルにロードする方法の例を示します。

def create_table_from_query(self,
                            query,
                            dest_table,
                            how):
    body = {
        'configuration': {
            'query': {
                'destinationTable': {
                    'projectId': your_project_id,
                    'tableId': dest_table,
                    'datasetId': your_dataset_id
                },
                'writeDisposition': how,
                'query': query,
            },
        }
    }

    response = self.connector.jobs().insert(projectId=self._project_id,
                                            body=body).execute()
    self.wait_job_completion(response['jobReference']['jobId'])

def wait_job_completion(self, job_id):
    while True:
        response = self.connector.jobs().get(projectId=self._project_id,
                                             jobId=job_id).execute()
        if response['status']['state'] == 'DONE':
            return

how入力は、ドキュメントのこのフィールドで使用可能なオプション( "WRITE_TRUNCATE"、 "WRITE_APPEND"など)を受け入れます。

たとえば、csvファイルからデータをロードできます。この場合、configuration変数は次の行に沿って定義されます。

"configuration": {
  "load": {
    "fieldDelimiter": "\t"
    "sourceFormat": "CSV"
    "destinationTable": {
      "projectId": your_project_id,
      "tableId": table_id,
      "datasetId": your_dataset_id
    },
    "writeDisposition": "WRITE_TRUNCATE"
    "schema": schema,
    "sourceUris": file_location_in_google_cloud_storage
  },
}

(例として、タブで区切られたcsvファイルを使用します。jsonファイルの場合もあります。ドキュメントでは、使用可能なオプションについて説明します)。

Jobs()の実行は、完了するまでに時間がかかります(そのため、wait_job_completionメソッドを作成しました)。ただし、リアルタイムストリーミングと比較すると安価なはずです。

ご不明な点がございましたら、お気軽にお問い合わせください。

16
Willian Fuks