【问题标题】:Unable to insert Pandas dataframes with NaN (or None) values into BigQuery tables when defining table_schema定义 table_schema 时,无法将具有 NaN(或 None)值的 Pandas 数据帧插入 BigQuery 表
【发布时间】:2020-06-07 12:37:05
【问题描述】:

我正在使用pandas_gbq.to_gbq()DataFrame 导出到具有NULL 值的col1 的Google BigQuery。

>>>df
col1    day
apple   2019-03-01
None    2019-03-02
banana  2019-03-02
None    2019-03-03

>>>df.dtypes
col1   object
day    datetime64[ns]
dtype: object

在不定义表架构的情况下,我可以在 BigQuery 中成功导出一个表,其中 null 值位于 col1

from google.cloud import bigquery
import pandas as pd
import pandas_gbq

pandas_gbq.to_gbq(df
        ,table_name
        ,project_id='project-dev'
        ,chunksize=None
        ,if_exists='replace'
        )

BigQuery 中的默认表架构:

col1   STRING      NULLABLE
day    TIMESTAMP   NULLABLE

但是,当我尝试在 BigQuery 中将 day 定义为 DATE 类型时,因为我不想要 TIMESTAMP 类型,我遇到了错误(我尝试过 NaN 和 None;都遇到了错误)。

table_schema = [{'name':'day', 'type':'DATE'}]

pandas_gbq.to_gbq(df
        ,table_name
        ,project_id='project-dev'
        ,chunksize=None
        ,if_exists='replace'
        ,table_schema=table_schema
        )

错误信息:

在 df ,table_schema=table_schema 文件“/Users/xxx/anaconda3/lib/python3.6/site-packages/pandas_gbq/gbq.py”,第 1224 行,在 to_gbq 进度条=进度条, 文件“/Users/xxx/anaconda3/lib/python3.6/site-packages/pandas_gbq/gbq.py”,第 606 行,在 load_data self.process_http_error(ex) 文件“/Users/xxx/anaconda3/lib/python3.6/site-packages/pandas_gbq/gbq.py”,第 425 行,在 process_http_error raise GenericGBQException("原因:{0}".format(ex)) pandas_gbq.gbq.GenericGBQException: 原因:400 读取数据时出错,错误信息:CSV 表遇到太多错误,放弃。行数:1;错误: 1. 请查看 errors[] 集合了解更多详情。

我已经阅读了pandas_gbq 的文档,但我仍然无法弄清楚。

https://pandas-gbq.readthedocs.io/en/latest/api.html#pandas_gbq.to_gbq

有人能指出我正确的方向吗?谢谢。

【问题讨论】:

  • 您是否尝试过为所有列定义表架构?
  • @WTK,根据文档,如果您提供规范 DATE 格式的 string,它将被读取为 DATE ,这里是link。我还在带有虚拟数据的笔记本中进行了一些测试,并且效果很好。我将日期字段保留为 "YYYY-MM-DD" 格式,并将字符串字段保留为 "None" 值,并且它起作用了。 UI 中的 bigQuery 架构是 DATESTRING。我可以和你分享我的测试。
  • @Sab 是的,我确实尝试为所有列定义,但我得到了同样的错误。
  • @AlexandreMoraes 感谢您分享该链接。我使用df['day'].dt.strftime('%Y-%m-%d') 将 [day] 的 dtypes 更改为字符串,然后像上面那样定义表模式,然后它就可以工作了!
  • @WTK,我很高兴知道它有效。我根据我的评论做出了回答,以进一步帮助社区。如果您能接受并投票,我将不胜感激。

标签: python pandas null google-bigquery


【解决方案1】:

我是根据我在评论部分提供的建议来写这个答案的。

根据documentation,如果您提供规范DATE 格式的String,它将在BigQuery 中被读取为DATE .规范格式如下:

  • YYYY:四位数年份

  • [M]M:一位或两位数的月份

  • [D]D:一位或两位数的天

因此,在如上所述更改类型和格式后,您将能够根据需要定义架构,否则 BigQuery 会将其识别为 DATE。

正如我在评论中提到的,我已经运行了一些测试来确认和举例说明我的建议,我将分享代码只是为了进一步帮助社区。我在 AI Platform 中使用 Jupyter Notebook 运行以下示例代码:

!pip install pandas_gbq

from google.cloud import bigquery 
import pandas as pd


table_schema = [{'name':'my_datetime', 'type':'DATE'},{'name':'my_string', 'type':'string'}]
df = pd.DataFrame(
    {
        "my_datetime": ["2020-01-01", "2020-01-01", "2020-01-01"],
        "my_string": ['a1',None, 'a3'],
    }
)

df.to_gbq(destination_table='data_frame.data_set', project_id='project_id', if_exists='replace')

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2019-03-28
    • 1970-01-01
    • 2020-03-04
    • 2020-05-29
    • 2021-08-17
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多