2017-10-24 32 views
1

SQLAlchemyによって生成された、その出所を示すクエリにコメントを追加する方法を理解しようとしています。SQLAlchemyクエリに文脈コメントを追加する

私はprefix_withメソッドを認識していますが、 'SELECT'の後に接頭辞が置かれるだけなので、満足できません。実際のクエリロジックから完全に分離したいと思っています。

これを処理するカーソル実行コールバックを追加する解決策を見つけました。詳細はhereです。この私の問題は、私が追加したいコメントの種類は、クエリがどこから実行されているかによって異なります。

ので、例えば、私は次のよう...

 
class SomeTableCountMetric(object): 

    def __init__(self): 
    session = sessionmaker(bind=engine, info={ 'src' : self.__class__.__name__ }) 

    def get(self): 
    return self.session.query(func.count(SomeTable.id)).all() 

ような何かをしたいと順番に生成されたクエリは、そう

 
SELECT COUNT(some_tables.id) FROM some_tables /* { 'src' : SomeTableCountMetric } */ 

もしている、基本的に、私は」セッションやクエリオブジェクトに任意の値を渡すことができ、コールバックメソッド(接続、カーソル、コンテキスト)で使用できる引数の1つから取得できます。

これを行うことは可能ですか、これを実装する別の方法がありますか?

また、これが良いパターンのように見えるかどうかについての考えはありますか?

答えて

2

connectionには、ユーザー定義のデータを格納できるinfo辞書があります。セッションにコメント情報を格納し、after_beginを介して関連付けられたconnectionに渡すことができます。その後、(他のanswerで提案されているように)実行前にSQLステートメントにコメントを追加することができます。

# Our session factory, typically is a scoped session 
Session = sessionmaker(bind=engine) 

# Pass `session` contextual info to `connection` 
@event.listens_for(Session, 'after_begin') 
def session_on_after_begin(session, transaction, connection): 
    if 'src' in session.info: 
    connection.info['src'] = session.info['src'] 


# Append comments to statement 
@event.listens_for(engine, "before_cursor_execute", retval=True) 
def comment_sql_calls(conn, cursor, statement, parameters, context, executemany): 
    if 'src' in conn.info: 
     statement = statement + " -- %s" % conn.pop('src') 
    return statement, parameters 


class SomeTableCountMetric(object): 

    def __init__(self, session=None): 
     if session is None: 
      session = Session() 
    self.session = session 
    self.session.info['src'] = 'some info' 

    def get(self): 
    return self.session.query(func.count(SomeTable.id)).all() 

try: 
    qo = SomeTableCountMetric() 
    qo.get() 
    qo.session.close() 
except: 
    qo.session.rollback() 
+0

ありがとうございます!魅力のように働いた。 before_cusor_executeコールバックはconn.info.pop( 'src')を実行するはずですが、マイナーコメント – Raphi

関連する問題