Na grande maioria dos casos, a "stringification" de uma instrução ou consulta SQLAlchemy é tão simples quanto:
print str(statement)
Isso se aplica tanto a um ORM Query
quanto a qualquer select()
outra declaração.
Nota : a resposta detalhada a seguir está sendo mantida na documentação do sqlalchemy .
Para obter a instrução compilada em um dialeto ou mecanismo específico, se a própria declaração ainda não estiver vinculada a uma, você pode passar para compile () :
print statement.compile(someengine)
ou sem um motor:
from sqlalchemy.dialects import postgresql
print statement.compile(dialect=postgresql.dialect())
Quando é fornecido um Query
objeto ORM , para obter o compile()
método, precisamos acessar apenas o acessador .statement primeiro:
statement = query.statement
print statement.compile(someengine)
No que diz respeito à estipulação original de que os parâmetros vinculados devem ser "incorporados" na sequência final, o desafio aqui é que o SQLAlchemy normalmente não é encarregado disso, pois isso é tratado adequadamente pelo DBAPI do Python, sem mencionar que os parâmetros vinculados são ignorados. provavelmente as falhas de segurança mais amplamente exploradas em aplicativos da web modernos. O SQLAlchemy possui capacidade limitada para fazer essa stringificação em determinadas circunstâncias, como a de emitir DDL. Para acessar essa funcionalidade, pode-se usar o sinalizador 'literal_binds', passado para compile_kwargs
:
from sqlalchemy.sql import table, column, select
t = table('t', column('x'))
s = select([t]).where(t.c.x == 5)
print s.compile(compile_kwargs={"literal_binds": True})
a abordagem acima tem as ressalvas de que ele é suportado apenas para tipos básicos, como ints e strings, e além disso, se um valor bindparam
sem um valor pré-definido for usado diretamente, também não será possível especificá-lo.
Para oferecer suporte à renderização literal embutida para tipos não suportados, implemente a TypeDecorator
para o tipo de destino que inclui um
TypeDecorator.process_literal_param
método:
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.c.x > 5).compile(
compile_kwargs={"literal_binds": True})
)
produzindo saída como:
SELECT mytable.x
FROM mytable
WHERE mytable.x > my_fancy_formatting(5)
sqlalchemy.engine
log do SQLAlchemy . Ele registra consultas e parâmetros de ligação, você apenas precisará substituir os espaços reservados de ligação pelos valores em uma sequência de consulta SQL prontamente construída.