2016-01-19 1 views
2

Я новичок в Python и SQLAlchemy, я пытаюсь понять, как выполнить несколько запросов вставки/обновления в одном SQL с помощью Python/SQLAlchemy:Как выполнить несколько запросов вставки/обновления в одном SQL с помощью Python/SQLAlchemy и MSSQL?

Requirement Выполнить несколько вставки/обновления в одном SQL:

DECLARE @age INT = 160 
INSERT INTO TEST_TABLE VALUES ('QZ_TEST', @age + 1) 
INSERT INTO TEST_TABLE VALUES ('QZ_TEST', 'not a number') 
INSERT INTO ANOTHER_TABLE VALUES ('QZ_TEST', @age + 2) 

Поймите, что этот запрос выглядит уродливым, но у нас есть много похожих запросов. (Мы используем устаревшую базу данных, которая составляет около 20 лет)

код Python

def OdbcEngineSA(driver, conn_str): 
    def connect(): 
     return pyodbc.connect(conn_str, autocommit=True, timeout=120) 
    return sqlalchemy.create_engine(driver + '://', creator=connect) 

def get_db_connection(): 
    return OdbcEngineSA('mssql', 'DSN=mssql;Server=server,15001;database=DEV;UID=user_abc;PWD=pw_') 

def main(): 
    db_connection = get_db_connection() 
    sql = """ 
    DECLARE @age INT = 160 
    INSERT INTO TEST_TABLE VALUES ('QZ_TEST', @age + 1) 
    INSERT INTO TEST_TABLE VALUES ('QZ_TEST', 'not a number') 
    INSERT INTO ANOTHER_TABLE VALUES ('QZ_TEST', @age + 2) 
    """ 
    try: 
     db_connection.execute(sql) 
     db_connection.commit() 
     logger.info('db updated') 
    except Exception as e: 
     logger.error('Exception captured as expected: %s', e) 
     db_connection.rollback() 

Пожалуйста, обратите внимание, что

INSERT INTO TEST_TABLE VALUES ('QZ_TEST', 'not a number') 

вызовет ошибку, если я побежал этот единственный запрос с моим SQL-клиентом: [S0001] [245] Ошибка конверсии при преобразовании значения varchar 'not a number' в тип данных int.

Я ожидаю исключение, захваченное Python, однако код Python работает без каких-либо исключений. Там не исключение захватывается Python, хотя я заменил SQL с:

BEGIN TRY 
     DECLARE @age INT = 160 
     INSERT INTO TEST_TABLE VALUES ('QZ_TEST', @age + 1) 
     INSERT INTO TEST_TABLE VALUES ('QZ_TEST', 'not a number') 
     INSERT INTO ANOTHER_TABLE VALUES ('QZ_TEST', @age + 2) 
END TRY 
    BEGIN CATCH 
     DECLARE @ErrorMessage NVARCHAR(4000) 
     DECLARE @ErrorSeverity INT 
     DECLARE @ErrorState INT 

     SELECT 
      @ErrorMessage = ERROR_MESSAGE(), 
      @ErrorSeverity = ERROR_SEVERITY(), 
      @ErrorState = ERROR_STATE() 

     RAISERROR (@ErrorMessage, 
        @ErrorSeverity, -- Level 16 
        @ErrorState 
        ) 
    END CATCH 

Мои вопросы

  • Могу ли я с помощью правильного метода для выполнения запроса?
  • Если мой код был в порядке, как я могу захватить фактическое исключение SQL из Python?

ответ

0

У команды execute может возникнуть проблема с подготовкой вашего заявления, поскольку на самом деле это несколько заявлений. За то, что вы пытаетесь сделать, я полагаю, вы можете захотеть взглянуть на executemany:

https://github.com/mkleehammer/pyodbc/wiki/Cursor#executemanysql-paras

Он принимает другую форму и связывает свои значения INSERT в кортежах в пределах списка.

Удачи вам!

+0

Спасибо! я понимаю, что «executemany» - это функция модуля ORM, однако я использую raw SQL и пытаюсь вставить в разные таблицы в одном запросе. вы знаете, есть ли «executemany/batch» для raw sql? Благодарю. – Guoliang

Смежные вопросы