如何用sqlAlchemy調用sql server存儲過程?用sqlAlchemy存儲過程
回答
引擎和連接有一個方法可以用於任意的sql語句,Sessions也是如此。例如:
results = sess.execute('myproc ?, ?', [param1, param2])
您可以使用outparam()
創建輸出參數,如果你需要(或綁定參數使用bindparam()
與isoutparam=True
選項)
只需執行與func
創建的過程,對象:
from sqlalchemy import create_engine, func
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite://', echo=True)
print engine.execute(func.upper('abc')).scalar() # Using engine
session = sessionmaker(bind=engine)()
print session.execute(func.upper('abc')).scalar() # Using session
這不適用於MySQL,'Function不存在。' – Profpatsch 2013-10-22 12:15:10
爲我工作,優雅和簡單的方式來調用存儲過程。官方說明_:數據:'.func'構造只有有限的支持調用 獨立的「存儲過程」,特別是那些有特殊 參數化問題。 見:參考:'stored_procedures'有關如何使用 的DBAPI級''callproc細節()''方法完全傳統的存儲 procedures._ 代碼爲我這樣的人:'session.execute( FUNC。your_proc_name(param1,param2))' – Niyojan 2016-07-12 08:37:14
假設您已經使用sessionmaker()創建了會話,則可以使用以下功能:
def exec_procedure(session, proc_name, params):
sql_params = ",".join(["@{0}={1}".format(name, value) for name, value in params.items()])
sql_string = """
DECLARE @return_value int;
EXEC @return_value = [dbo].[{proc_name}] {params};
SELECT 'Return Value' = @return_value;
""".format(proc_name=proc_name, params=sql_params)
return session.execute(sql_string).fetchall()
現在你可以用簡單的參數一樣,執行存儲過程「MyProc的」:
params = {
'Foo': foo_value,
'Bar': bar_value
}
exec_procedure(session, 'MyProc', params)
這看起來很容易受到SQL注入的影響。 – 2016-03-21 13:46:58
這確實很脆弱。用'execute(sql_string,params = ...)'傳遞命名參數以讓引擎轉義參數值更好。 @Profpatsch的答案已經做到了。 – 2016-06-01 12:25:07
我該如何收集輸出參數?即,我的聲明是: 'EXEC dbo.next_rowid'dbo','workorder_feature',@id OUTPUT;'我如何獲得ID? – roemhildtg 2017-03-21 14:15:14
出於迫切需要爲我的項目,我寫了一個處理存儲過程調用的函數。
在這裏你去:
import sqlalchemy as sql
def execute_db_store_procedure(database, types, sql_store_procedure, *sp_args):
""" Execute the store procedure and return the response table.
Attention: No injection checking!!!
Does work with the CALL syntax as of yet (TODO: other databases).
Attributes:
database -- the database
types -- tuple of strings of SQLAlchemy type names.
Each type describes the type of the argument
with the same number.
List: http://docs.sqlalchemy.org/en/rel_0_7/core/types.html
sql_store_procudure -- string of the stored procedure to be executed
sp_args -- arguments passed to the stored procedure
"""
if not len(types) == len(sp_args):
raise ValueError("types tuple must be the length of the sp args.")
# Construch the type list for the given types
# See
# http://docs.sqlalchemy.org/en/latest/core/sqlelement.html?highlight=expression.text#sqlalchemy.sql.expression.text
# sp_args (and their types) are numbered from 0 to len(sp_args)-1
type_list = [sql.sql.expression.bindparam(
str(no), type_=getattr(sql.types, typ)())
for no, typ in zip(range(len(types)), types)]
try:
# Adapts to the number of arguments given to the function
sp_call = sql.text("CALL `%s`(%s)" % (
sql_store_procedure,
", ".join([":%s" % n for n in range(len(sp_args))])),
bindparams=type_list
)
#raise ValueError("%s\n%s" % (sp_call, type_list))
with database.engine.begin() as connection:
return connection.execute(
sp_call,
# Don't do this at home, kids...
**dict((str(no), arg)
for (no, arg) in zip(range(len(sp_args)), sp_args)))
except sql.exc.DatabaseError:
raise
它的工作原理與CALL語法,因此MySQL應該按預期工作。我想,MSSQL使用EXEC而不是調用和一些不同的語法。因此,使其成爲服務器不可知論取決於你,但不應該太難。
使用SQLAlchemy在MySQL中調用存儲過程的最簡單方法是使用callproc
方法Engine.raw_connection()
。 call_proc
將需要調用存儲過程所需的過程名稱和參數。
def call_procedure(function_name, params):
connection = cloudsql.Engine.raw_connection()
try:
cursor = connection.cursor()
cursor.callproc(function_name, params)
results = list(cursor.fetchall())
cursor.close()
connection.commit()
return results
finally:
connection.close()
- 1. 從SQLAlchemy調用存儲過程
- 2. 從SqlAlchemy調用MSSQL存儲過程
- 3. Python sqlalchemy調用存儲過程
- 4. 使用SQLAlchemy創建存儲過程
- 5. 從sqlalchemy調用postgresql中的存儲過程
- 6. sqlalchemy在調用mysql存儲過程時出錯
- 7. 使用存儲過程調用存儲過程的異常iBATIS
- 8. 使用儲存在存儲過程
- 9. MS SQL SERVER 2005 + SQLAlchemy +存儲過程+輸出參數
- 10. SQLAlchemy - 執行存儲過程並填充類
- 11. sqlalchemy存儲過程執行的解析結果
- 12. 存儲過程
- 13. 存儲過程
- 14. 存儲過程
- 15. 存儲過程
- 16. 存儲過程
- 17. 存儲過程
- 18. 存儲過程
- 19. 存儲過程
- 20. 存儲過程
- 21. 存儲過程
- 22. 存儲過程
- 23. 存儲過程
- 24. 存儲過程
- 25. 存儲過程
- 26. 存儲過程
- 27. 存儲過程
- 28. 存儲過程
- 29. 存儲過程
- 30. 存儲過程
這不是數據庫不可知的。改用'sqlalchemy.sql.text'。 – Profpatsch 2013-10-22 14:38:22
順便說一句,如果你想訪問MS SQL Server中存儲過程返回的行,你需要'sess.execute('SET NOCOUNT ON')'。您可以在一個執行調用中執行該操作:'results = sess.execute('SET NOCOUNT ON; EXEC myproc?,?; SET NOCOUNT OFF',[param1,param2])'。 – 2016-03-21 13:46:18
這是一箇舊的線程,所以也許這是在sqlalchemy的新版本中已經改變的東西,但我必須使用字典而不是參數列表,並在原始sql中使用「:param_name」而不是「?」 。因此,上面的例子變成:'sess.execute('myproc:p1,:p2',{'p1':'value1','p2':'value2'})' – ThatAintWorking 2016-06-29 20:28:08