Pandas / Google BigQuery: la falta de coincidencia del esquema hace que la carga falle

El esquema en mi tabla de Google se ve así:

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 

Después de hacer pandas.read_gbq , obtengo un dataframe con dataframe de columna como este:

 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 

Ahora quiero usar to_gbq así que convierto mi dataframe local (que acabo de hacer) de estos tipos de datos:

 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 

a estos dtypes:

 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 

haciendo:

 df['price_datetime'] = df['price_datetime'].astype(object) 

Ahora yo (creo) estoy leído para usar to_gbq así que hago:

 import pandas pandas.io.gbq.to_gbq(df, , , if_exists='append')

pero me sale el error:

 --------------------------------------------------------------------------- InvalidSchema Traceback (most recent call last)  in () 1 a = time.time() ----> 2 pandas.io.gbq.to_gbq(df, 
, , if_exists='append') 3 b = time.time() 4 5 print(ba) 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.

Este es probablemente un problema relacionado con los pandas. Si verifica el código para to_gbq , verá que ejecuta este código:

 table_schema = _generate_bq_schema(dataframe) 

Donde _generate_bq_schema es dado por:

 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} 

Como puede ver, no hay ningún tipo de asignación a DATETIME . Esto inevitablemente se asigna al tipo STRING (ya que su dtype.kind es “O”) y luego se produce un conflicto.

El único trabajo por ahora que conozco sería cambiar su esquema de tabla de DATETIME a TIMESTAMP o STRING .

Probablemente sería una buena idea comenzar un nuevo problema en el repository pandas-bq solicitando actualizar este código para aceptar DATETIME también.

[EDITAR]:

He abierto este tema en su repository.

Tuve que hacer dos cosas que me solucionaron el problema. Primero, eliminé mi tabla y la volví a cargar con las columnas como tipos TIMESTAMP lugar de tipos DATETIME . Esto aseguró que el esquema coincidiera cuando el pandas.DataFrame con el tipo de columna datetime64[ns] se cargó usando to_gbq , que convierte datetime64[ns] al tipo TIMESTAMP y no al tipo DATETIME ( por ahora ).

Lo segundo que hice fue actualizar de pandas 0.19 a pandas 0.20 . Estas dos cosas resolvieron mi problema de una falta de coincidencia de esquema.