0

我正在使用sqlalchemy從python在MySql服務器上運行查詢。sqlalchemy在調用mysql存儲過程時出錯

我初始化的SQLAlchemy有:

engine = create_engine("mysql+mysqlconnector://{user}:{password}@{host}:{port}/{database}".format(**connection_params)) 
conn = engine.connect() 

哪裏connection_params是包含服務器訪問的詳細信息的字典。

我運行此查詢:

SELECT 
new_db.asset_specification.identifier_code, 
new_db.asset_specification.asset_name, 
new_db.asset_specification.asset_type, 
new_db.asset_specification.currency_code, 
new_db.sector_map.sector_description, 
new_db.super_sector_map.super_sector_description, 
new_db.country_map.country_description, 
new_db.country_map.country_macro_area 

FROM new_db.asset_specification 
INNER JOIN new_db.identifier_code_legal_entity_map on new_db.asset_specification.identifier_code = new_db.identifier_code_legal_entity_map.identifier_code 
INNER JOIN new_db.legal_entity_map on projecthf_db.identifier_code_legal_entity_map.legal_entity_code = new_db.legal_entity_map.legal_entity_code 
INNER JOIN new_db.sector_map on new_db.legal_entity_map.legal_entity_sector = new_db.sector_map.sector_code 
INNER JOIN new_db.super_sector_map on projecthf_db.legal_entity_map.legal_entity_super_sector = new_db.super_sector_map.super_sector_code 
INNER JOIN new_db.country_map on new_db.legal_entity_map.legal_entity_country = new_db.country_map.country_code 
WHERE new_db.asset_specification.identifier_code = str_identifier_code; 

使用conn.execute(query)(這裏我設置query等於上面的字符串)。

這運行得很好。

我試圖把我的查詢在存儲過程中,如:

CREATE DEFINER=`root`@`localhost` PROCEDURE `test_anag`(IN str_identifier_code varchar(100)) 
BEGIN 
SELECT 
new_db.asset_specification.identifier_code, 
new_db.asset_specification.asset_name, 
new_db.asset_specification.asset_type, 
new_db.asset_specification.currency_code, 
new_db.sector_map.sector_description, 
new_db.super_sector_map.super_sector_description, 
new_db.country_map.country_description, 
new_db.country_map.country_macro_area 

FROM new_db.asset_specification 
INNER JOIN new_db.identifier_code_legal_entity_map on new_db.asset_specification.identifier_code = new_db.identifier_code_legal_entity_map.identifier_code 
INNER JOIN new_db.legal_entity_map on projecthf_db.identifier_code_legal_entity_map.legal_entity_code = new_db.legal_entity_map.legal_entity_code 
INNER JOIN new_db.sector_map on new_db.legal_entity_map.legal_entity_sector = new_db.sector_map.sector_code 
INNER JOIN new_db.super_sector_map on projecthf_db.legal_entity_map.legal_entity_super_sector = new_db.super_sector_map.super_sector_code 
INNER JOIN new_db.country_map on new_db.legal_entity_map.legal_entity_country = new_db.country_map.country_code 
WHERE new_db.asset_specification.identifier_code = str_identifier_code; 

END 

我可以從MySQL工作臺查詢編輯器與CALL new_db.test_anag('000000')運行存儲過程,我得到了想要的結果(這是一個單行)。

現在,我嘗試運行:

res = conn.execute("CALL new_db.test_anag('000000')") 

但它失敗,出現以下異常

sqlalchemy.exc.InterfaceError: (mysql.connector.errors.InterfaceError) Use multi=True when executing multiple statements [SQL: "CALL projecthf_db.test_anag('0237400')"]

我環顧四周,但我找不到任何關於此錯誤的有用和愛我無法繞過它。我不是Mysql或sqlalchemy(或任何RDBMS)的專家,但這看起來應該很容易修復。讓我知道是否需要更多信息。

提前感謝您的幫助

回答

1

從閱讀related question可以看出,當executing stored procedures producing such,即使只有一個結果集產生了mysql.connector自動獲取並存儲多個結果集。 SQLAlchemy另一方面does not support multiple result sets – directly。要執行存儲過程,請使用callproc()。要訪問SQLAlchemy中的DB-API遊標,您必須使用raw connection。在mysql.connector的情況下,可以使用stored_results()訪問生成的結果集:

from contextlib import closing 

# Create a raw MySQLConnection 
conn = engine.raw_connection() 

try: 
    # Get a MySQLCursor 
    with closing(conn.cursor()) as cursor: 
     # Call the stored procedure 
     result_args = cursor.callproc('new_db.test_anag', ['000000']) 
     # Iterate through the result sets produced by the procedure 
     for result in cursor.stored_results(): 
      result.fetchall() 

finally: 
    conn.close() 
+0

令人驚歎的答案,感謝所有參考。非常感謝你 :-) – gionni