¿Cómo puedo hacer que esqueleto genere una cadena SQL para mí?

86

¿Cómo puedo hacer que esqueleto genere una cadena SQL a partir de una fromdeclaración?

La documentación de toRawSqldice que "puede activar el registro de consultas de persistente". Intenté todas las formas posibles de MonadLoggereso que pude entender, pero nunca imprimí ningún SQL. La misma documentación también dice "usar manualmente esta función ... es posible pero tedioso". Sin embargo, no QueryTypese exportan constructores del tipo ni funciones que devuelvan valores del tipo . ¡Me las arreglé para evitar esto notando que QueryTypees un newtypey usando unsafeCoerce!

También me vi obligado a proporcionar un Connection(que obtuve a través de SQLite) aunque no debería haber necesidad de conectarse a una base de datos para generar el SQL.

Esto es lo que tengo. Debe haber una mejor manera.

withSqliteConn ":memory:" $
    \conn -> return $ toRawSql SELECT
                               (unsafeCoerce ((const mempty)
                                  :: a -> Text.Lazy.Builder.Builder))
                               (conn, initialIdentState) myFromStatement)

http://hackage.haskell.org/package/esqueleto-1.3.4.2/docs/Database-Esqueleto-Internal-Sql.html

Tom Ellis
fuente
2
Creo que la razón por la que necesita darle una conexión es porque es polimórfica en la base de datos y usa SqlPersistinstancias inferidas para generar cadenas SQL específicas de la base de datos .
Thomas
2
Sin embargo, la conexión y el tipo de base de datos subyacente son cosas diferentes. Debería ser posible generar puramente la cadena SQL.
Tom Ellis

Respuestas:

2

En el tiempo transcurrido desde que se publicó esta pregunta, esqueletoha pasado por una serie de revisiones importantes. A partir de la versión 2.1.2 , y varias versiones anteriores, el QueryType aparámetro que necesitaba su unsafeCoerceha sido eliminado toRawSql; esa gran verruga ya no es necesaria.

Como se implementa actualmente, Connectionse requiere un. Creo que, como lo indica el nombre del sinónimo de tipo IdentInfo, esqueletousa esto para construir identificadores en la consulta. Puede, por ejemplo, agregar el nombre de la base de datos. Realmente no he sondeado la fuente con suficiente profundidad. Baste decir que pasar una conexión falsa (es decir undefined) no funciona; No sé si se podría implementar una conexión simulada. Su solución parece viable.

El resto de su solución debería funcionar bien. Dado que toRawSqles explícitamente una función interna, la API aquí parece razonable. Aunque otros señalan que "debería" ser posible generar una cadena de conexión neutra, que aparece fuera del alcance de toRawSql.

Mencionas que no podrías usar MonadLoggercomo se recomienda. ¿Qué intentaste y qué pasó?

Christian Conkle
fuente
MonadLoggerDesafortunadamente, no recuerdo con qué lo intenté . Fue hace bastante tiempo.
Tom Ellis
¿Tiene un proyecto de prueba a mano para ver si toRawSqlfunciona ahora para el caso de uso de esta pregunta? Configuré un esqueletoentorno para probarlo, pero no he tenido tiempo de averiguarlo persistenty toda la otra maquinaria para construir y consumir una consulta real.
Christian Conkle
No tengo ningún tipo de entorno de prueba ni ningún proyecto esqueleto, lo siento.
Tom Ellis