我的google表中的模式如下所示:
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:
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,所以我从以下数据类型转换我的本地数据帧(我刚刚创建的):
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对于这些数据类型:
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通过执行以下操作:
df['price_datetime'] = df['price_datetime'].astype(object)现在我(认为)我正在使用to_gbq,所以我这样做了:
import pandas
pandas.io.gbq.to_gbq(df, <table_name>, <project_name>, if_exists='append')但我得到了错误:
---------------------------------------------------------------------------
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.发布于 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。这两件事解决了我的模式不匹配问题。
发布于 2017-07-07 08:13:31
这可能是一个与熊猫有关的问题。如果您检查to的代码,您将看到它运行以下代码:
table_schema = _generate_bq_schema(dataframe)其中_generate_bq_schema由:
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更改为TIMESTAMP或STRING。
在pandas-bq存储库上发起一个新问题,要求更新此代码以接受DATETIME,这可能是一个好主意。
编辑
我已经在他们的存储库中打开了这个issue。
发布于 2020-10-19 23:36:44
我研究了pandas从模式中生成的内容,并用它来发现不同之处。
from pandas_gbq import schema
schema.generate_bq_schema(df)使用此代码片段的输出来找出不同之处。
https://stackoverflow.com/questions/44953463
复制相似问题