首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pandas/Google BigQuery:模式不匹配导致上传失败

Pandas/Google BigQuery:模式不匹配导致上传失败
EN

Stack Overflow用户
提问于 2017-07-06 23:41:28
回答 5查看 6.1K关注 0票数 4

我的google表中的模式如下所示:

代码语言:javascript
复制
price_datetime : DATETIME,
symbol         : STRING,
bid_open       : FLOAT,
bid_high       : FLOAT,
bid_low        : FLOAT,
bid_close      : FLOAT,
ask_open       : FLOAT,
ask_high       : FLOAT,
ask_low        : FLOAT,
ask_close      : FLOAT

在我执行pandas.read_gbq之后,我得到了一个具有如下列数据类型的dataframe

代码语言:javascript
复制
price_datetime     object
symbol             object
bid_open          float64
bid_high          float64
bid_low           float64
bid_close         float64
ask_open          float64
ask_high          float64
ask_low           float64
ask_close         float64
dtype: object

现在我想使用to_gbq,所以我从以下数据类型转换我的本地数据帧(我刚刚创建的):

代码语言:javascript
复制
price_datetime    datetime64[ns]
symbol                    object
bid_open                 float64
bid_high                 float64
bid_low                  float64
bid_close                float64
ask_open                 float64
ask_high                 float64
ask_low                  float64
ask_close                float64
dtype: object

对于这些数据类型:

代码语言:javascript
复制
price_datetime     object
symbol             object
bid_open          float64
bid_high          float64
bid_low           float64
bid_close         float64
ask_open          float64
ask_high          float64
ask_low           float64
ask_close         float64
dtype: object

通过执行以下操作:

代码语言:javascript
复制
df['price_datetime'] = df['price_datetime'].astype(object)

现在我(认为)我正在使用to_gbq,所以我这样做了:

代码语言:javascript
复制
import pandas
pandas.io.gbq.to_gbq(df, <table_name>, <project_name>, if_exists='append')

但我得到了错误:

代码语言:javascript
复制
---------------------------------------------------------------------------
InvalidSchema                             Traceback (most recent call last)
<ipython-input-15-d5a3f86ad382> in <module>()
      1 a = time.time()
----> 2 pandas.io.gbq.to_gbq(df, <table_name>, <project_name>, if_exists='append')
      3 b = time.time()
      4 
      5 print(b-a)

C:\Users\me\AppData\Local\Continuum\Anaconda3\lib\site-packages\pandas\io\gbq.py in to_gbq(dataframe, destination_table, project_id, chunksize, verbose, reauth, if_exists, private_key)
    825         elif if_exists == 'append':
    826             if not connector.verify_schema(dataset_id, table_id, table_schema):
--> 827                 raise InvalidSchema("Please verify that the structure and "
    828                                     "data types in the DataFrame match the "
    829                                     "schema of the destination table.")

InvalidSchema: Please verify that the structure and data types in the DataFrame match the schema of the destination table.
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-07-07 22:45:42

我必须做两件事来解决这个问题。首先,我删除了我的表并用TIMESTAMP类型而不是DATETIME类型的列重新上载了它。这确保了当使用to_gbq将列类型为datetime64[ns]pandas.DataFrame上载到时,模式是匹配的,这会将datetime64[ns]转换为TIMESTAMP类型,而不是DATETIME类型(for now)。

我做的第二件事是从pandas 0.19升级到pandas 0.20。这两件事解决了我的模式不匹配问题。

票数 6
EN

Stack Overflow用户

发布于 2017-07-07 08:13:31

这可能是一个与熊猫有关的问题。如果您检查to的代码,您将看到它运行以下代码:

代码语言:javascript
复制
table_schema = _generate_bq_schema(dataframe)

其中_generate_bq_schema由:

代码语言:javascript
复制
def _generate_bq_schema(df, default_type='STRING'):
    """ Given a passed df, generate the associated Google BigQuery schema.
    Parameters
    ----------
    df : DataFrame
    default_type : string
        The default big query type in case the type of the column
        does not exist in the schema.
    """

    type_mapping = {
        'i': 'INTEGER',
        'b': 'BOOLEAN',
        'f': 'FLOAT',
        'O': 'STRING',
        'S': 'STRING',
        'U': 'STRING',
        'M': 'TIMESTAMP'
    }

    fields = []
    for column_name, dtype in df.dtypes.iteritems():
        fields.append({'name': column_name,
                       'type': type_mapping.get(dtype.kind, default_type)})

    return {'fields': fields}

如您所见,没有到DATETIME的类型映射。这不可避免地被映射到类型STRING (因为它的dtype.kind是"O"),然后冲突就发生了。

据我所知,目前唯一的解决办法是将表模式从DATETIME更改为TIMESTAMPSTRING

在pandas-bq存储库上发起一个新问题,要求更新此代码以接受DATETIME,这可能是一个好主意。

编辑

我已经在他们的存储库中打开了这个issue

票数 5
EN

Stack Overflow用户

发布于 2020-10-19 23:36:44

我研究了pandas从模式中生成的内容,并用它来发现不同之处。

代码语言:javascript
复制
from pandas_gbq import schema
schema.generate_bq_schema(df)

使用此代码片段的输出来找出不同之处。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44953463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档