In den allermeisten Fällen ist die "Stringifizierung" einer SQLAlchemy-Anweisung oder -Abfrage so einfach wie:
print str(statement)
Dies gilt sowohl für ein ORM Query
als auch für eine select()
oder andere Aussage.
Hinweis : Die folgende detaillierte Antwort wird in der sqlalchemy-Dokumentation beibehalten .
Um die Anweisung so zu kompilieren, dass sie für einen bestimmten Dialekt oder eine bestimmte Engine kompiliert wurde, können Sie diese an compile () übergeben , wenn die Anweisung selbst noch nicht an eine gebunden ist :
print statement.compile(someengine)
oder ohne Motor:
from sqlalchemy.dialects import postgresql
print statement.compile(dialect=postgresql.dialect())
Wenn wir ein ORM- Query
Objekt erhalten, müssen compile()
wir zuerst nur auf den .statement- Accessor zugreifen , um an die Methode zu gelangen :
statement = query.statement
print statement.compile(someengine)
In Bezug auf die ursprüngliche Bestimmung, dass gebundene Parameter in die endgültige Zeichenfolge "eingebunden" werden sollen, besteht die Herausforderung darin, dass SQLAlchemy normalerweise nicht damit beauftragt ist, da dies vom Python-DBAPI angemessen behandelt wird, ganz zu schweigen von der Umgehung gebundener Parameter wahrscheinlich die am häufigsten genutzten Sicherheitslücken in modernen Webanwendungen. SQLAlchemy ist unter bestimmten Umständen, z. B. bei der Emission von DDL, nur eingeschränkt in der Lage, diese Stringifizierung durchzuführen. Um auf diese Funktionalität zuzugreifen, kann das Flag 'literal_binds' verwendet werden, das an Folgendes übergeben wird 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})
Der obige Ansatz hat die Einschränkungen, dass er nur für Basistypen wie Ints und Strings unterstützt wird. Wenn ein bindparam
Wert ohne voreingestellten Wert direkt verwendet wird, kann er dies auch nicht stringifizieren.
Um das Inline-Literal-Rendering für nicht unterstützte Typen zu unterstützen, implementieren Sie ein TypeDecorator
für den Zieltyp, das eine
TypeDecorator.process_literal_param
Methode enthält:
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})
)
Produktion produzieren wie:
SELECT mytable.x
FROM mytable
WHERE mytable.x > my_fancy_formatting(5)
sqlalchemy.engine
Protokoll von SQLAlchemy tippen . Es protokolliert Abfragen und Bindungsparameter. Sie müssen lediglich die Bindungsplatzhalter durch die Werte in einer leicht zu erstellenden SQL-Abfragezeichenfolge ersetzen.