【问题标题】:How to write array of string values from Pandas to Google Big Query如何将 Pandas 中的字符串值数组写入 Google Big Query
【发布时间】:2020-06-19 09:03:18
【问题描述】:

我目前正在尝试将 Pandas Dataframe (Python 3.x) 写入 Google Big Query。该表有一个 dtype 对象列,其中包含一个字符串值数组。

sample of pandas table 我的目标是创建一个维护嵌套表结构的 BQ 表,如下所示: sample of Big Query table 具有以下架构: schema of Big Query table

我使用 google-cloud-bigquery 库,因为它允许 df 转换为每个文档支持嵌套数组值的 Parquet 格式:

使用的代码:

client = bigquery.Client()
table_id = 'dataset.table'

job_config = bigquery.LoadJobConfig(
    schema = [
            bigquery.SchemaField('route_id', 'INTEGER'),
            bigquery.SchemaField('types', 'STRING', mode='REPEATED')
    ], 
    writeDisposition="WRITE_APPEND"
)

job = client.load_table_from_dataframe(
    df, 
    table_id, 
    job_config=job_config,
)

# Wait for the load job to complete.
job.result()

但不幸的是,我收到以下错误消息:

BadRequest: 400 读取数据时出错,错误消息:提供 架构与文件不兼容 'prod-scotty-76a528bc-407d-4224-8951-c8ff0c71faa1'。字段“类型”是 在提供的与 NULLABLE 不匹配的架构中指定为 REPEATED 文件中指定的。

到目前为止已经尝试过什么:

  1. 使用 RECORD 字段类型

但这导致了以下错误: https://github.com/googleapis/python-bigquery/issues/21

  1. 根本不在 python 中提供任何架构(并允许 Python/BQ 自行整理)

令人惊讶的是,这适用于第一次迭代 (CREATE_IF_NEEDED) 在 BQ 中创建一个表,该表维护嵌套结构并自动应用以下模式: auto-applied schema of BQ table,但如果您尝试再次追加确切的表,则会失败,返回与 1 下相同的错误。

有什么建议或提示吗?

【问题讨论】:

    标签: python arrays python-3.x pandas google-bigquery


    【解决方案1】:

    当您将数据加载到尚未解析的 BigQuery 时,parquet 中的架构与数组的解释架构之间似乎存在 a mismatch

    通过使用开源库pandas-gcp,我已经能够正确上传带有数组的数据框:

    import pandas as pd
    import pandas_gbq
    
    d = {'nested_string': [['hi', 'keloke'], ['io', 'ready']], 'route_id': [83833, 4487]}
    df = pd.DataFrame(data = d)
    
    table_id = "dataset.table"
    project_id = 'my_project'
    
    pandas_gbq.to_gbq(
        df, table_id, project_id=project_id, if_exists='replace',
    )
    

    没有第三方工具的其他可能的解决方法:

    · 改用数据流

    · 从 python 文件中,将数据帧以 csv 格式保存在 Google 存储桶中,并从 BigQuery 中提取

    你认为这些对你有用吗?

    【讨论】:

    • 感谢艾伯特!我尝试了使用 pandas_gbq 库的类似方法,但该方法仅在表不存在的情况下才有效。我看到您在该表存在的情况下替换该表。如果您尝试追加到 BQ 中的现有表,是否想知道您的方法是否也有效?现在我已经绕过了这个问题 a) 在 pandas df 中将数组从 [a,b,c] 重新格式化为 a,b,c b) 将其作为字符串写回 BQ c) 在 BQ 本身中使用 SPLIT 字符串函数 cloud.google.com/bigquery/docs/reference/standard-sql/… 来恢复嵌套模式 d) 存储表谢谢
    • 它适用于我之前在 BQ 上创建的表(空)。现在我还尝试追加 (if_exists = 'append') 并将新行添加到现有行中。
    • 你能做到吗?
    • 这只适用于 if_exists="replace" 因为它创建了一个新表,其中重复的列被视为字符串(在您的情况下为nested_string)。
    • 当你设置 [if_exists="append"] 时观察到的行为是什么?
    猜你喜欢
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多