FECHA de SQL Server recuperada en pandas como una cadena

Cuando extraigo una variable “Fecha” de SQL Server en Python / Pandas, aparece como un ‘Objeto’. He instalado y probado varios controladores (los controladores comentados que se muestran en el código), cada vez con los mismos resultados:

import pandas as pd import pyodbc conn_str = ( r'Driver={SQL Server Native Client 11.0};' # r'Driver={SQL Server Native Client 10.0};' # r'Driver={ODBC Driver 11 for SQL Server};' # r'Driver={ODBC Driver 13 for SQL Server};' # r'Driver={SQL Server};' r'Server=MyServer;' r'Database=MyDB;' r'Trusted_Connection=yes;' ) cnxn = pyodbc.connect(conn_str) sql = ( "Select cast('2017-08-19' as date) [DateVar]" ", cast('2017-08-19' as datetime) [DateTimeVar]" ", cast('2017-08-19' as datetime2) [DateTime2Var]" ) d2 = pd.read_sql(sql,cnxn) cnxn.close() print(d2.dtypes) 

El resultado devuelto es:

 DateVar object DateTimeVar datetime64[ns] DateTime2Var datetime64[ns] dtype: object 

Quiero que DateVar sea una fecha y hora. ¿Alguna idea de por qué esto está pasando?

El mismo problema que este tipo: pyodbc devuelve los campos DATE de SQL Server como cadenas. Pero la solución para él fue usar {SQL Server Native Client 10.0}, que he instalado y no me funciona.

La versión de SQL Server a la que me estoy conectando es:

 Microsoft SQL Server 2012 (SP3) (KB3072779) - 11.0.6020.0 (X64) Oct 20 2015 15:36:27 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1  (Build 7601: Service Pack 1) 

Actualizaciones

1>

Basado en los comentarios de Max, he intentado sqlalchemy, pero sin suerte, esto todavía me devuelve una cadena:

 import sqlalchemy as sa engine = sa.create_engine('mssql+pyodbc://MyDatabase/MyDB?driver=SQL+Server+Native+Client+10.0') d2 = pd.read_sql(sql, engine) 

2>

Basándose en la Q de Flipper, he hecho esto con solo un cursor de Pyodbc y parece que el tipo de datos de fecha correcta se devuelve en el cursor cuando se usa el Native Client 11.0:

 (('DateVar', datetime.date, None, 10, 10, 0, True), ('DateTimeVar', datetime.datetime, None, 23, 23, 3, True), ('DateTime2Var', datetime.datetime, None, 27, 27, 7, True)) 

Esto sugeriría que el problema está en el manejo de Pandas del dtype datetime.date al cargar en un dataframe.

Use el parámetro parse_dates de pandas.read_sql para especificar que los valores de la columna DateVar se convierten explícitamente a datetime en la carga del dataframe.

Fragmento de código original actualizado:

 ... d2 = pd.read_sql(sql=sql, con=cnxn, # explicitly convert DATE type to datetime object parse_dates=["DateVar"]) cnxn.close() print(d2.dtypes) 

Devoluciones

 DateVar datetime64[ns] DateTimeVar datetime64[ns] DateTime2Var datetime64[ns] dtype: object 

Probado con pyodbc 4.0.17, pandas 0.20.3 y SQL Server 2014 en Windows.

Trate de usar SQLAlchemy de la siguiente manera:

 from sqlalchemy import create_engine engine = create_engine("mssql+pyodbc://scott:tiger@myhost:port/databasename?driver=SQL+Server+Native+Client+10.0")