Add an officially supported query compilation function

Issue #2886 new
Alex Grönholm created an issue

Often, when my queries are not accepted by the backend (ProgrammingError) I want to look at the generated SQL and tinker with it, executing it directly on the backend until I figure out what's wrong. Trouble is, when I print the query with str(query), it gives me the non-interpolated version of the query (ie. with the placeholders not filled in). Many people have been asking for a way to get a compiled version of the query, which could be copypasted directly to psql or whatever.

SQLACodegen also requires a method for compiling expressions, given a dialect. I've used an adapted version of this: http://stackoverflow.com/a/5698357/242021 However, the 0.8.3 update broke it. One of my tests is now giving me:

AttributeError: Neither 'Label' object nor 'Comparator' object has an attribute 'table'

That's one more reason why I'm requesting an official compiling method that won't break with micro version updates of SQLAlchemy.

Comments (4)

  1. Alex Grönholm reporter

    I've fixed the acute issue with sqlacodegen, but the general need for this remains.

  2. Mike Bayer repo owner
    • changed component to orm
    • changed milestone to 0.9.xx

    well there's several aspects to this, one is whether str() takes into account the current engine so that the statement renders as it would on the backend, the other is the thing with the bounds which is sort of something else. as far as binds as strings, that will have a lot of unsupported edge cases as we don't implement stringifiers for all types - and in fact it's only as of 0.9 that we even have the ability to support per-type stringifiers.

    the recipe for all of those things together is as follows:

    def query_as_str_w_binds(query):
       context = query._compile_context()
       context.statement.use_labels = True
       conn = query.session.connection(mapper=query._mapper_zero_or_none(), clause=context.statement)
       return unicode(context.statement.compile(conn, compiler_kwargs={"literal_binds": True}))
    

    literal binds definitely needs to be an option.

  3. Log in to comment