Ошибка SQLAlchemy: попытка завершить транзакцию не удалась. Соответствующая транзакция не найдена

Я установил:

  • Убунту (18.04)
  • Python (3.6.8)
  • msodbcsql17 (драйвер Microsoft ODBC 17 для SQL Server)
  • SQLAlchemy (1.3.5)
  • Панды (0.24.2)

и я хочу создать просто подтверждение концепции, используя SQLAlchemy с хранилищем данных SQL Azure. Тем не менее, когда я пытаюсь выполнить запрос по модели Customer, который сопоставлен с таблицей представления клиентов с помощью кода:

import urllib

from sqlalchemy import create_engine
from sqlalchemy import Column, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

db_username = 'username'
db_password = 'password'
db_database = 'dbname'
db_hostname = 'dbhost'
db_driver = 'ODBC Driver 17 for SQL Server'
db_port = '1433'

db_connectionString = f"DRIVER={{{db_driver}}}; SERVER={{{db_hostname}}}; DATABASE={{{db_database}}}; UID={{{db_username}}}; PWD={{{db_password}}}; PORT={{{db_port}}};"

engine_params = urllib.parse.quote_plus(db_connectionString)

engine = create_engine(f"mssql+pyodbc:///?odbc_connect={engine_params}", echo=True)

Base = declarative_base()

class Customer(Base):
    __tablename__ = 'customers'

    id = Column('Customer_ID', Integer, primary_key=True)

Session = sessionmaker(bind=engine)
session = Session()

customers_count = session.query(Customer).count()

session.close()

выдается следующее исключение:

ProgrammingError: (pyodbc.ProgrammingError) ('42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]111214;An attempt to complete a transaction has failed. No corresponding transaction found. (111214) (SQLEndTran)

Пожалуйста, имейте в виду, что я могу использовать движок SQLAlchemy с пандами и запускать собственные SQL-запросы, такие как:

data_frame = pandas.read_sql("SELECT COUNT(*) FROM customers", engine)

Однако мне нужно использовать высокоуровневый API запросов SQLAlchemy:

customers_count = session.query(Customer).count()

Любая помощь могла бы быть полезна.

3 ответа

Документация SQLAlchemy для mssql+pyodbc://… только что был обновлен, чтобы включить следующее (для SQLA 1.4 / 2.0):

Хранилище данных SQL Azure не поддерживает транзакции, и это может вызвать проблемы с поведением SQLAlchemy «автозапуск» (и неявной фиксацией / откатом). Мы можем избежать этих проблем, включив автокоммит как на уровне pyodbc, так и на уровне движка:

      connection_url = sa.engine.URL.create(
    "mssql+pyodbc",
    username="scott",
    password="tiger",
    host="dw.azure.example.com",
    database="mydb",
    query={
        "driver": "ODBC Driver 17 for SQL Server",
        "autocommit": "True",
    },
)
engine = create_engine(connection_url).execution_options(
    isolation_level="AUTOCOMMIT"
)

Чтобы добавить к ответу @Gord Thompson (извините, поскольку у меня недостаточно репутации, чтобы комментировать). Для SQLAlchemy 1.4.32; если у вас есть права администратора только для схемы, а не для всей базы данных, установка уровня изоляции транзакций вызовет ошибку, когда библиотека проверит, действителен ли уровень изоляции для базы данных. Чтобы обойти это, я немного изменил код.

      connection_url = sa.engine.URL.create(
    "mssql+pyodbc",
    username="scott",
    password="tiger",
    host="dw.azure.example.com",
    database="mydb",
    query={
        "driver": "ODBC Driver 17 for SQL Server",
        "autocommit": "True",
    },
)
engine = create_engine(connection_url).execution_options()

Это даст вам предупреждение, но работает.

После многих проб и ошибок это сработало для меня:

      engine = create_engine("mssql+pyodbc://username:password@server_name/database_name?"
                            "driver=ODBC+Driver+17+for+SQL+Server"
                            "&authentication=ActiveDirectoryPassword"
                            "&autocommit=True")
Другие вопросы по тегам