2015-06-20 122 views
0

在分析應用程序時,我發現SQLAlchemy編譯SQL是佔用應用程序大部分CPU時間的任務之一。我已經明確了綁定的參數,但是看起來SQLAlchemy只在需要執行時才編譯查詢。有沒有辦法讓SQLAlchemy預編譯查詢?

有沒有辦法讓它預編譯查詢,以便在執行之前只需要極少的工作來替換綁定的參數?

+0

你使用什麼數據庫? –

+0

這可能會幫助你:http://stackoverflow.com/questions/4617291/how-do-i-get-a-raw-compiled-sql-query-from-a-sqlalchemy-expression – IanAuld

+0

Simeon:PostgreSQL;伊恩:謝謝 –

回答

0

有一種方法...種。我已經在模塊解析時間定義查詢:

class MyClass(object): 
    # This works (slow) 
    query = select(...).where(...).order_by('distance').limit(1) 
    ... 

    @classmethod 
    def issue_query(cls, **params): 
     cls.engine.execute(cls.query, params) 

但SQLAlchemy中只保留編譯MyClass.query只有當MyClass.issue_query被稱爲(它被稱爲每次)。我注意到,在定義了查詢爲text()使得它非常快(120us VS 600us)...但str(query)編譯查詢到幾乎是一個text()的說法,所以我試着將其定義爲:

class MyClass(object): 
    # This doesn't work 
    query = text(str(select(...).where(...).order_by('distance').limit(1))) 
    ... 

    @classmethod 
    def issue_query(cls, **params): 
     cls.engine.execute(cls.query, params) 

但是,SQLAlchemy試圖理解order_by()中的'distance',並將中的1轉換爲綁定參數(即從查詢中刪除該值)。這可以解決一點點黑客:

class MyClass(object): 
    # This works (fast) 
    query = text(str(select(...).where(...).order_by(text('distance')).limit(text('1')))) 
    ... 

    @classmethod 
    def issue_query(cls, **params): 
     cls.engine.execute(cls.query, params) 
+0

剛發現你不能以這種方式使用任何綁定參數。甚至沒有使用bindparam()。 –

相關問題