2015-06-23 5 views
7

Przykład:Sqlalchemy - jak uzyskać surowy sql z instrukcji insert(), update() z powiązanymi paramami?

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()) 

Rezultat tego jest:

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

Pytanie brzmi, jak zrobić sqlalchemy generować smth takiego:

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

Dla select, compile_kwargs= {"literal_binds": True} rozwiązuje problemu, ale to nie działa dla update, insert.

Dzięki za pomoc.

P.S. Muszę budować surowe kwerendy sql z orm, więc wszelkie sugestie innych orm, które mają łatwy sposób generowania raw sql, są mile widziane.

+0

możliwy duplikat [SQLAlchemy: wydrukuj aktualne zapytanie] (http://stackoverflow.com/questions/5631078/sqlalchemy-print-the-actual-query) – metatoaster

+0

spróbuj umieścić w cudzysłowach? – Busturdust

+0

Zobacz FAQ SQLAlchemy: [Jak wyrenderować wyrażenia SQL jako łańcuchy, ewentualnie z wbudowanymi parametrami związanymi?] (Http://docs.sqlalchemy.org/en/rel_1_0/faq/sqlexpressions.html#how-do-i-render -sql-wyrażenia-jako-łańcuchy-ewentualnie-z-związanymi-parametrami-podkreślonymi). Powinieneś użyć 'literal_binds = True'. – van

Odpowiedz

0

Po prostu uruchom ten fragment kodu na python 2.7 i SQLAlchemy (1.0.13) i zadziałało.

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}) 

moje wyjście jest:

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

Może coś jest nie tak z twoim otoczeniu?

+0

Nie działa z opcją slqlalchemy v1.0.11, która jest dostarczana wraz z Ubuntu 16.04 xenial. – wolfmanx

+0

I zawiedzie, gdy tylko użyjesz wartości datetime.datetime: NotImplementedError: Nie wiem, jak literalnie zacytować wartość datetime.date (2016, 10, 3) – wolfmanx

1

Rozwiązanie przy użyciu kompilacji_kwargs - jak w reklamie gdzie indziej - działa tylko częściowo, tj. Dla prostych typów danych, takich jak liczba całkowita lub ciąg (od 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  | -- | 
+-------------+----------------+--------+---------------+----------+ 

W zależności od wymagań i ograniczeń, następujące rozwiązania będzie wykonać zadanie:

  • Jeśli można użyć sqlalchemy v1.0.13 lub powyżej, najprostszym rozwiązaniem jest w this answer. Przedstawiona tam klasa LiteralDialect nadal wymaga poprawnego cytowania typów danych, takich jak data-godzina. Chociaż nie jest kompletny, dodawanie brakujących typów danych jest bardzo proste. I niestety musisz naprawić None do null() dla INSERT/UPDATE.

  • Jeśli można użyć SQLAlchemy v1.0.11 i potrzebują tylko SELECT oświadczenia (nie INSERT/UPDATE), można również skorzystać z rozwiązania z the above answer. SQLAlchemy v1.0.11 jest dystrybuowany z Ubuntu 16.04 xenial, aktualną wersją LTS (stan na marzec 2017).

Jeśli utkniesz w starej wersji SQLAlchemy, nie ma słodkiego i prostego podejścia do problemu.

Więc wymyśliłem some code supporting SQL compilation zapytań (SELECT), a także instrukcji INSERT i UPDATE. Kod działa z SQLAlchemy v0.7.9 - v1.1.6 i Python2/Python3.

A detailed (and hilarious) analysis of the various features jest zawarty jako doctest.

Odpowiednie odcinki kodowe to:

Powiązane problemy