如何在SQLAlchemy中執行原始SQL?如何在SQLAlchemy-flask應用程序中執行原始SQL
我有一個python web應用程序,它通過SQLAlchemy在燒瓶上運行,並與數據庫接口。
我需要一種方法來運行原始SQL。該查詢涉及多個表連接以及嵌入視圖。
我已經試過:
connection = db.session.connection()
connection.execute(<sql here>)
但我不斷收到網關錯誤。
如何在SQLAlchemy中執行原始SQL?如何在SQLAlchemy-flask應用程序中執行原始SQL
我有一個python web應用程序,它通過SQLAlchemy在燒瓶上運行,並與數據庫接口。
我需要一種方法來運行原始SQL。該查詢涉及多個表連接以及嵌入視圖。
我已經試過:
connection = db.session.connection()
connection.execute(<sql here>)
但我不斷收到網關錯誤。
你試過:
result = db.engine.execute("<sql here>")
或:
from sqlalchemy import text
sql = text('select name from penguins')
result = db.engine.execute(sql)
names = []
for row in result:
names.append(row[0])
print names
如果你做了一個插入或更新,你如何提交交易? –
如果您使用的是原始SQL,那麼您可以控制事務,因此您必須自己發佈'BEGIN'和'COMMIT'語句。 – Miguel
我試過了,它似乎不適合我。非常好奇。 –
您是否嘗試過使用connection.execute(text(<sql here>), <bind params here>)
和綁定參數描述in the docs?這可以幫助解決許多參數格式和性能問題。也許網關錯誤是超時?綁定參數傾向於使複雜的查詢執行速度大幅提高。
根據[文檔](http://docs.sqlalchemy.org/en/rel_0_8/core/tutorial.html#using-text),它應該是'connection.execute(文本(
是的,你當然是。我修正了這個,謝謝。 – jhnwsk
文檔:SQL Expression Language Tutorial - Using Text
例如:
from sqlalchemy.sql import text
connection = engine.connect()
# recommended
cmd = 'select * from Employees where EmployeeGroup == :group'
employeeGroup = 'Staff'
employees = connection.execute(text(cmd), group = employeeGroup)
# or - wee more difficult to interpret the command
employeeGroup = 'Staff'
employees = connection.execute(
text('select * from Employees where EmployeeGroup == :group'),
group = employeeGroup)
# or - notice the requirement to quote "Staff"
employees = connection.execute(
text('select * from Employees where EmployeeGroup == "Staff"'))
for employee in employees: logger.debug(employee)
# output
(0, u'Tim', u'Gurra', u'Staff', u'991-509-9284')
(1, u'Jim', u'Carey', u'Staff', u'832-252-1910')
(2, u'Lee', u'Asher', u'Staff', u'897-747-1564')
(3, u'Ben', u'Hayes', u'Staff', u'584-255-2631')
到sqlalchemy文檔的鏈接似乎已過時。這是更近的:http://docs.sqlalchemy.org/en/latest/core/tutorial.html#using-textual-sql – Carl
我可以問爲什麼我們使用'=='? –
@Jake Berger非常感謝您。我已經浪費了將近一天的時間來尋找這個答案。我只是直接執行SQL而不轉換爲文本。每當我的where子句中有%students%時,就會發生錯誤。對你的回答表示熱烈的掌聲。 –
如果你想使用一個會話(如你的問題建議),利用其execute
方法直接:
import sqlalchemy
from sqlalchemy.orm import sessionmaker, scoped_session
engine = sqlalchemy.create_engine('my connection string')
Session = scoped_session(sessionmaker(bind=engine))
s = Session()
result = s.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})
下面的威力特定於我的數據庫驅動程序(psycopg2);我不確定。無論如何,這是我如何拉出我的價值觀。
from collections import namedtuple
Record = namedtuple('Record', result.keys())
records = [Record(*r) for r in result.fetchall()]
for r in records:
print(r)
關鍵是撥打fetchall()
。 namedtuple
部分只是我發現通過提供基於名稱的訪問使我的生活更輕鬆。
此外,這是交易沒有手動管理它。說make_session
是創建一個會話的功能:
>>> s1 = make_session()
>>> s1.execute('CREATE TABLE blah (id INTEGER)')
<sqlalchemy.engine.result.ResultProxy object at 0x02CD86F0>
>>> s1.commit()
>>>
>>> s1.execute('INSERT INTO blah VALUES (1)')
<sqlalchemy.engine.result.ResultProxy object at 0x02CD8870>
>>> s1.execute('SELECT * FROM blah').fetchall()
[(1,)]
>>>
>>> s2 = make_session()
>>> s2.execute('SELECT * FROM blah').fetchall()
[]
>>> s2.close()
>>>
>>> s1.commit()
>>>
>>> s2 = make_session()
>>> s2.execute('SELECT * FROM blah').fetchall()
[(1,)]
>>> s2.close()
>>> s1.close()
你可以SELECT SQL的查詢結果使用from_statement()
和text()
如圖所示here。你不必以這種方式處理t ules。對於具有表名「用戶」,你可以嘗試一類用戶爲例,
from sqlalchemy.sql import text
.
.
.
user = session.query(User).from_statement(
text("SELECT * FROM users where name=:name")).\
params(name='ed').all()
return user
result = db.engine.execute(text("<sql here>"))
執行<sql here>
但除非你在autocommit
模式不提交。所以,插入和更新不會反映在數據庫中。
要更改後提交,做
result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))
我建議你只使用http://pythonhosted.org/Flask-SQLAlchemy/也很快忘記了執行原始的SQL查詢。 –
我已經看過,但我找不到有關運行更新的教程。我寧願不學習語法,也不想學習相當長的(約20行)SQL查詢。 – starwing123
@MarkusUnterwaditzer我曾經認爲,但現在我強烈反對。原始的,適當參數化的SQL通常比一堆產生它的函數調用和對象更易於讀取和維護。它還爲您提供數據庫的全部功能,而無需跳過這些環節,使ORM生成正確的語法(如果甚至可能的話),並使ORM不會做出意想不到的事情。您可能會問這個問題:「那麼爲什麼要使用SQLAlchemy?」,而我唯一的答案是,「現有的應用程序使用它並改變所有內容太昂貴。」 – jpmc26