In the vast majority of cases, a โstrictโ SQLAlchemy statement or query is as simple as:
print str(statement)
This applies to both ORM Query and any select() or other expression.
Note : the following detailed answer is supported in sqlalchemy documentation .
To get an instruction compiled for a specific dialect or engine, if the operator itself is not yet tied to one, you can pass this to compile () :
print statement.compile(someengine)
or without engine:
from sqlalchemy.dialects import postgresql print statement.compile(dialect=postgresql.dialect())
When providing an ORM Query object, to get the compile() method, we only need access to .statement first:
statement = query.statement print statement.compile(someengine)
regarding the initial caveat that related parameters should be โembeddedโ in the final string, the problem here is that SQLAlchemy usually does not ask this question, since it is correctly handled using Python DBAPI, not to mention circumventing related parameters are probably the most widely used security holes in modern web applications. SQLAlchemy has limited ability to perform this stringing under certain circumstances, such as when using DDL. To access this function, you can use the "literal_binds" flag passed to compile_kwargs :
from sqlalchemy.sql import table, column, select t = table('t', column('x')) s = select([t]).where(tcx == 5) print s.compile(compile_kwargs={"literal_binds": True})
The above approach has reservations that it is only supported for basic types such as ints and strings, and in addition, if a bindparam without a predefined value is used directly, it will not be able to do this either.
To support inline literal rendering for types that are not supported, run a TypeDecorator for the target type, which includes TypeDecorator.process_literal_param :
from sqlalchemy import TypeDecorator, Integer class MyFancyType(TypeDecorator): impl = Integer def process_literal_param(self, value, dialect): return "my_fancy_formatting(%s)" % value from sqlalchemy import Table, Column, MetaData tab = Table('mytable', MetaData(), Column('x', MyFancyType())) print( tab.select().where(tab.cx > 5).compile( compile_kwargs={"literal_binds": True}) )
output output as:
SELECT mytable.x FROM mytable WHERE mytable.x > my_fancy_formatting(5)