Lectura de tablas mysql usando pandas y parámetros nombrados en la consulta

Intento ejecutar la siguiente consulta.

SELECT user_id, user_agent_id, requests FROM riskanalysis_user_http_ua_stats WHERE since>= :since AND until< :until' 

Intento el siguiente código de pandas

 sql = 'SELECT user_id, user_agent_id, requests ' \ 'FROM riskanalysis_user_http_ua_stats ' \ 'WHERE since>= :since AND until< :until' dataframe_records = pd.read_sql_query(sql, engine, params={'since':datetime_object, 'until':datetime_object} 

y me sale el siguiente error

 sqlalchemy.exc.ArgumentError: Could not parse rfc1738 URL from string 'SELECT user_id, user_agent_id, requests FROM riskanalysis_user_http_ua_stats WHERE since>= :since AND until< :until' 

Estoy usando pymysql como el controlador y la base de datos MySQL. ¿Cómo paso los parámetros nombrados en una consulta de SQL?

EDIT 1: se corrigió el orden de los parámetros pero ahora obtengo lo siguiente

 sqlalchemy.exc.ProgrammingError: (pymysql.err.ProgrammingError) (1064, u"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':since AND until= :since AND until< :until'] [parameters: {'since': datetime.datetime(2015, 6, 18, 0, 0, tzinfo=tzutc()), 'until': datetime.datetime(2015, 6, 18, 0, 2, tzinfo=tzutc())}] 

Según la documentación de pandas.read_sql_query ,

params : list, tuple or dict, opcional, predeterminado: ninguno

Lista de parámetros para pasar al método de ejecución. La syntax utilizada para pasar parámetros depende del controlador de la base de datos. Consulte la documentación del controlador de la base de datos para ver cuál de los cinco estilos de syntax descritos en el estilo de PEP 249 es compatible. P.ej. para psycopg2, usa% (nombre) s así que usa params = {‘nombre’: ‘valor’}

Si luego observa el estilo de PEP 249 , verá muchas opciones. Pero la documentación de execute de PyMySQL establece que

Si args es una lista o tupla,% s puede usarse como un marcador de posición en la consulta.

Si args es un dict,% (nombre) s puede usarse como un marcador de posición en la consulta.

Entonces, aplicando a su caso, eso sería:

 sql = 'SELECT user_id, user_agent_id, requests ' \ 'FROM riskanalysis_user_http_ua_stats ' \ 'WHERE since>= %s AND until< %s' dataframe_records = pd.read_sql_query(sql, engine, params=(datetime_object, datetime_object)) 

o

 sql = 'SELECT user_id, user_agent_id, requests ' \ 'FROM riskanalysis_user_http_ua_stats ' \ 'WHERE since>= %(since)s AND until< %(until)s' dataframe_records = pd.read_sql_query(sql, engine, params={'since':datetime_object, 'until':datetime_object}) 

pandas.read_sql_query espera una consulta sql antes que el motor, e intenta analizar su consulta como un URI de base de datos.
Consulte https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_sql_query.html

 dataframe_records = pd.read_sql_query(sql, engine, params={'since':datetime_object,'until':datetime_object} ) 

Como se señaló, su controlador no reconoce los marcadores de posición con nombre mediante la syntax de dos puntos. La consulta se pasa como a MySQL, que luego se queja de los marcadores de posición, ya que son errores de syntax. Una solución es usar la construcción SQLAlchemy text() , que se encarga de traducir los marcadores de posición nombrados a un formato comprendido por su controlador:

 from sqlalchemy import text sql = text(sql) dataframe_records = pd.read_sql_query(sql, engine, params={'since':datetime_object, 'until':datetime_object})