2015-06-23 37 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中。

相关的代码部分是: