Note: cette réponse est maintenu sur le sqlalchemy de la documentation.
tout d'abord, pour ceux qui éprouvent cette question, remarque que le "stringification" de SQLAlchemy instruction ou de la Requête dans la grande majorité des cas, est aussi simple que:
print str(statement)
cela s'applique à la fois à un ORM Query
ainsi que tout select()
ou toute autre déclaration. En outre, pour obtenir la déclaration de la compilation d'un dialecte spécifique ou le moteur, si la déclaration n'est pas déjà lié à un, vous pouvez passer ce à compiler():
print statement.compile(someengine)
ou sans moteur:
from sqlalchemy.dialects import postgresql
print statement.compile(dialect=postgresql.dialect())
Lorsque l'ORM Query
objet, afin d'obtenir à l' compile()
méthode, nous avons seulement besoin d'avoir accès à l' .déclaration de l'accesseur en premier:
statement = query.statement
print statement.compile(someengine)
en ce qui concerne la stipulation originale que les paramètres liés à des "inline" dans la chaîne finale, le défi ici est que SQLAlchemy, normalement, n'est pas chargé à cet effet, comme cela est géré de manière appropriée par l'Python DBAPI, pour ne pas mentionner de contourner les paramètres liés est probablement le plus largement exploité les failles de sécurité dans les applications web modernes. SQLAlchemy a une capacité limitée pour ce faire stringification dans certaines circonstances comme celle d'émettre DDL. Pour accéder à cette fonctionnalité, on peut utiliser le 'literal_binds' drapeau, passé de 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})
l'approche ci-dessus est la mise en garde qu'il est uniquement pris en charge pour la base de
les types, tels que des entiers et des chaînes, et en outre, si un bindparam
sans un pré-réglage de la valeur est utilisée directement, il ne sera pas en mesure de
stringify que ce soit.
À l'appui de inline interprétation littérale pour les types non pris en charge, de mettre en œuvre
un TypeDecorator
de la cible, du type qui comprend un
TypeDecorator.process_literal_param
méthode:
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})
)
de la production comme:
SELECT mytable.x
FROM mytable
WHERE mytable.x > my_fancy_formatting(5)