2015-06-23 43 views
7

例子:Sqlalchemy - 如何從insert(),update()語句和綁定參數獲取原始sql?

from sqlalchemy.dialects import mysql 
from sqlalchemy import Integer, Column, update, insert 
from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 

class Test(Base): 
    __tablename__ = "test" 

    a = Column(Integer, primary_key=True) 
    b = Column(Integer) 


update_stmt = update(Test).where(Test.a == 1).values(b=2) 
print update_stmt.compile(dialect=mysql.dialect(), compile_kwargs= {"literal_binds": True}) 

insert_stmt = insert(Test).values(a=1, b=1) 
print insert_stmt.compile(dialect=mysql.dialect()) 

結果的是這樣的:

UPDATE test SET b=%s WHERE test.a = %s 
INSERT INTO test (a, b) VALUES (%s, %s) 

的問題是如何讓SQLAlchemy的產生水木清華這樣的:

UPDATE test SET b=2 WHERE test.a = 1 
INSERT INTO test (a, b) VALUES (1, 1) 

對於selectcompile_kwargs= {"literal_binds": True}解決了這個問題,但它不適用於updateinsert

感謝您的任何幫助。

P.S.我需要從orm構建原始的sql查詢,因此任何其他orms的建議,都可以通過簡單的方式生成原始sql,這是值得歡迎的。

+0

可能重複的[SQLAlchemy:打印實際查詢](http://stackoverflow.com/questions/5631078/sqlalchemy-print-the-actual-query) – metatoaster

+0

嘗試把它放在引號中? – Busturdust

+0

請參閱SQLAlchemy常見問題解答:[如何將SQL表達式呈現爲字符串,可能綁定參數內聯?](http://docs.sqlalchemy.org/en/rel_1_0/faq/sqlexpressions.html#how-do-i-render -sql表達式-作爲串 - 可能與 - 結合的參數內聯)。你應該使用'literal_binds = True'。 – van

回答

0

我只是運行這個片段python 2.7SQLAlchemy (1.0.13)它的工作。

from sqlalchemy.dialects import mysql 
from sqlalchemy import Integer, Column, update, insert 
from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 


class Test(Base): 
    __tablename__ = "test" 

    a = Column(Integer, primary_key=True) 
    b = Column(Integer) 


update_stmt = update(Test).where(Test.a == 1).values(b=2) 
print update_stmt.compile(dialect=mysql.dialect(), compile_kwargs={"literal_binds": True}) 

insert_stmt = insert(Test).values(a=1, b=1) 
print insert_stmt.compile(dialect=mysql.dialect(), compile_kwargs={"literal_binds": True}) 

我的輸出是:

UPDATE test SET b=2 WHERE test.a = 1 
INSERT INTO test (a, b) VALUES (1, 1) 

也許事情是不對您的環境?

+0

它不適用於ubuntu 16.04 xenial附帶的slqlalchemy v1.0.11。 – wolfmanx

+0

只要使用datetime.datetime值,它就會失敗:NotImplementedError:不知道如何引用字面值datetime.date(2016,10,3) – wolfmanx

1

使用compile_kwargs溶液 - 如別處公佈 - 工程只是部分的,即簡單數據類型,如整數或字符串(如SQLAlchemy的V1.1.6的)。

+-------------+----------------+--------+---------------+----------+ 
| SQA version | compile_kwargs | SELECT | INSERT/UPDATE | datetime | 
+=============+================+========+===============+==========+ 
| 0.7.9  |  --  | -- |  --  | -- | 
+-------------+----------------+--------+---------------+----------+ 
| 0.9.4  |  √  | 1/2 |  --  | -- | 
+-------------+----------------+--------+---------------+----------+ 
| 1.0.11  |  √  | √ |  --  | -- | 
+-------------+----------------+--------+---------------+----------+ 
| 1.0.13  |  √  | √ |  1/2  | -- | 
+-------------+----------------+--------+---------------+----------+ 
| 1.1.6  |  √  | √ |  1/2  | -- | 
+-------------+----------------+--------+---------------+----------+ 

根據要求和限制,以下解決方案將做的工作:

  • 如果你能使用SQLAlchemy v1.0.13以上,最簡單的辦法是在this answer提供。在那裏呈現的類仍然需要提供像日期時間這樣的數據類型的正確引用。雖然它不完整,但添加缺失的數據類型非常簡單。不幸的是,你必須修復Nonenull() INSERT/UPDATE。

  • 如果你能使用SQLAlchemy v1.0.11版,需要只能選擇語句(不是INSERT/UPDATE),你也可以使用該解決方案從the above answer。 SQLAlchemy v1.0.11隨ubuntu 16.04 xenial發佈,即當前的LTS版本(截至2017年3月)。

如果你被卡住了一些舊版本的SQLAlchemy的,沒有甜蜜和簡單的解決問題的方法。

所以我想出了some code supporting SQL compilation的查詢(SELECT)以及INSERT和UPDATE語句。該代碼適用於SQLAlchemy v0.7.9 - v1.1.6和Python2/Python3。

A detailed (and hilarious) analysis of the various features包含在doctest中。

相關的代碼部分是: