En la gran mayoría de los casos, la "cadena" de una declaración o consulta SQLAlchemy es tan simple como:
print str(statement)
Esto se aplica tanto a un ORM Query
como a cualquier select()
otra declaración.
Nota : la siguiente respuesta detallada se mantiene en la documentación de sqlalchemy .
Para obtener la declaración como compilada en un dialecto o motor específico, si la declaración en sí no está vinculada a una, puede pasar esto a compile () :
print statement.compile(someengine)
o sin motor:
from sqlalchemy.dialects import postgresql
print statement.compile(dialect=postgresql.dialect())
Cuando se le da un Query
objeto ORM , para obtener el compile()
método solo necesitamos acceder primero al descriptor de acceso de declaración :
statement = query.statement
print statement.compile(someengine)
con respecto a la estipulación original de que los parámetros vinculados deben "insertarse" en la cadena final, el desafío aquí es que SQLAlchemy normalmente no tiene la tarea de esto, ya que Python DBAPI lo maneja adecuadamente, sin mencionar que omitir los parámetros vinculados es probablemente los agujeros de seguridad más ampliamente explotados en las aplicaciones web modernas. SQLAlchemy tiene una capacidad limitada para hacer esta cadena en ciertas circunstancias, como la de emitir DDL. Para acceder a esta funcionalidad, se puede usar el indicador 'literal_binds', que se pasa a 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})
el enfoque anterior tiene la advertencia de que solo es compatible con tipos básicos, como ints y cadenas, y además, si bindparam
se usa directamente un valor sin un valor preestablecido, tampoco podrá encadenar eso.
Para admitir la representación literal en línea para los tipos no admitidos, implemente un TypeDecorator
para el tipo de destino que incluye un
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})
)
produciendo resultados como:
SELECT mytable.x
FROM mytable
WHERE mytable.x > my_fancy_formatting(5)
sqlalchemy.engine
registro de SQLAlchemy . Registra consultas y parámetros de enlace, solo tendría que reemplazar los marcadores de posición de enlace con los valores en una cadena de consulta SQL fácilmente construida.