SQLAlchemy: 実際のクエリを印刷する 質問する

SQLAlchemy: 実際のクエリを印刷する 質問する

バインド パラメータではなく、値を含むアプリケーションの有効な SQL を出力できるようにしたいのですが、SQLAlchemy でこれを行う方法が明確ではありません (設計によるものだと思います)。

この問題を一般的な方法で解決した人はいますか?

ベストアンサー1

ほとんどの場合、SQLAlchemy ステートメントまたはクエリの「文字列化」は次のように簡単です。

print(str(statement))

これは、ORMQueryselect()その他のステートメントの両方に適用されます。

:以下の詳細な回答は、sqlalchemy ドキュメント

特定の方言またはエンジンにコンパイルされたステートメントを取得するには、ステートメント自体がまだバインドされていない場合は、これをコンパイル():

print(statement.compile(someengine))

またはエンジンなし:

from sqlalchemy.dialects import postgresql
print(statement.compile(dialect=postgresql.dialect()))

ORMオブジェクトが与えられた場合、メソッドにアクセスするQueryには、compile()。声明アクセサファースト:

statement = query.statement
print(statement.compile(someengine))

バインドされたパラメータは最終的な文字列に「インライン化」されるという当初の規定に関して、ここでの課題は、これは Python DBAPI によって適切に処理されるため、SQLAlchemy は通常これを実行しないということです。また、バインドされたパラメータをバイパスすることは、現代の Web アプリケーションで最も広く悪用されているセキュリティ ホールであることは言うまでもありません。SQLAlchemy は、DDL を発行する場合など、特定の状況でこの文字列化を行う能力が限られています。この機能にアクセスするには、次のものに渡される 'literal_binds' フラグを使用できます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}))

上記のアプローチには、int や文字列などの基本型に対してのみサポートされているという注意点があり、さらに、bindparam事前設定された値のない が直接使用されると、それを文字列化することもできません。

サポートされていない型のインラインリテラルレンダリングをサポートするには、メソッドTypeDecoratorを含むターゲット型に を実装します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.c.x > 5).compile(
        compile_kwargs={"literal_binds": True})
)

次のような出力が生成されます:

SELECT mytable.x
FROM mytable
WHERE mytable.x > my_fancy_formatting(5)

おすすめ記事