How can I get esqueleto to generate an SQL string for me?

In the time since this question was posted, esqueleto has gone through a number of major revisions. As of version 2.1.2, and several earlier versions, the QueryType a parameter that necessitated your unsafeCoerce has been removed from toRawSql; that major wart is no longer necessary.

As currently implemented, a Connection is required. I believe that, as indicated by the type synonym name, IdentInfo, esqueleto uses this to build identifiers in the query. It may, for example, add the database name. I haven't really plumbed the source in enough depth. Suffice it to say, passing a fake connection (i.e. undefined) doesn't work; I don't know if a mock connection could be implemented. Your solution seems workable.

The rest of your solution should work fine. Since toRawSql is explicitly an internal function, the API here seems reasonable. Although others note that it "should" be possible to generate a connection-neutral string, that appears outside the scope of toRawSql.

You mention that you couldn't use MonadLogger as recommended. What did you try, and what happened?