使用Python将数据从datasteam加载到BigQuery

时间:2018-06-26 08:36:23

标签: python google-bigquery

我正在使用API​​调用从服务中检索数据。 数据是嵌套的Json,其数组也可能包含Json对象。

示例: enter image description here

基本上我想将其上传到BigQuery中的表中。 我为每个数组创建了一个表。杰森(Jason)的物品在同一张桌子中打开包装。 例如:

Orders: All customer fields, all ShippingAdress, orderDateUtc etc..
Orders_items:  orderid, discountEach, giftTo etc..
Order_items_historicalCategories: ....

我不确定执行此操作的最佳方法。 我可以通过API调用(数据流)创建CSV文件,然后对每个CSV使用COPY上载它们,但这似乎过多。我正在寻找一种跳过CSV创建的方法。

是否存在可以处理此数据并将其直接上传到表的运算符或程序包?我认为我需要做的事情已经由许多其他组织完成,但是我没有在文档中看到任何“内置”方法来做 https://cloud.google.com/bigquery/docs/loading-data

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

基本上,您必须使用load json data using python遵循有关如何nested and repeated fields的文档。例如,使用后一个链接中的模式,您可以按以下方式加载嵌套和重复的JSON数据(可以对找到的here的示例数据进行测试):

import sys

def load_nested_json():
    from google.cloud import bigquery
    client = bigquery.Client()

    dataset_id, table_id, uri = sys.argv[1:]
    dataset_ref = client.dataset(dataset_id)
    job_config = bigquery.LoadJobConfig()
    job_config.schema = [
        bigquery.SchemaField('id', 'STRING', mode='NULLABLE'),
        bigquery.SchemaField('first_name', 'STRING', mode='NULLABLE'),
        bigquery.SchemaField('last_name', 'STRING', mode='NULLABLE'),
        bigquery.SchemaField('dob', 'DATE', mode='NULLABLE'),
        bigquery.SchemaField('addresses', 'RECORD', mode='REPEATED', fields=[
            bigquery.SchemaField('status', 'STRING', mode='NULLABLE'),
            bigquery.SchemaField('address', 'STRING', mode='NULLABLE'),
            bigquery.SchemaField('city', 'STRING', mode='NULLABLE'),
            bigquery.SchemaField('state', 'STRING', mode='NULLABLE'),
            bigquery.SchemaField('zip', 'STRING', mode='NULLABLE'),
            bigquery.SchemaField('numberOfYears', 'STRING', mode='NULLABLE'),
        ]),
    ]
    table_ref = dataset_ref.table(table_id)
    # Uncomment following lines to also create the destination table
    # table = bigquery.Table(table_ref, job_config.schema)
    # table = client.create_table(table)

    # print('Created table {}'.format(table.full_table_id))

    job_config.source_format = "NEWLINE_DELIMITED_JSON"

    load_job = client.load_table_from_uri(
        uri,
        table_ref,
        job_config=job_config)  # API request

    assert load_job.job_type == 'load'

    load_job.result()  # Waits for table load to complete.

    assert load_job.state == 'DONE'

if __name__ == '__main__':
    load_nested_json()