Originally posted by ww2406 July 7, 2022
Describe the bug
Hello!
Problem: Unable to use transactions with Azure Synapse Analytics
Description: ODBC Error 111214 is returned: An attempt to complete a transaction has failed. No corresponding transaction found.
Other notes: Transactions function properly when using pyodbc directly [see MCVE]. I saw this post by gordthompson in response to a question on StackOverflow (and since added to the documentation) that
Azure SQL Data Warehouse does not support transactions
but this is outdated. Azure Synapse Analytics does support transactions in most cases; see this Microsoft documentation:
As you would expect, SQL pool supports transactions as part of the data warehouse workload. However, to ensure SQL pool is maintained at scale, some features are limited when compared to SQL Server. This article highlights the differences.
To Reproduce
import pyodbc
import sqlalchemy as sa
import os
p_con_string = os.getenv("synapse_conn_pyodbc")
sa_eng_string = os.getenv("synapse_conn_sa")
p_con = pyodbc.connect(p_con_string)
engine = sa.create_engine(sa_eng_string)
p_cur = p_con.cursor()
p_cur.execute("INSERT INTO test VALUES ('test')")
p_con.commit()
p_con.close()
# No error
with engine.begin() as s_con:
stmt = sa.Text("INSERT INTO test VALUES ('test')")
s_con.execute(stmt)
# Traceback (most recent call last):
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3280, in _wrap_pool_connect
# return fn()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 310, in connect
# return _ConnectionFairy._checkout(self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 868, in _checkout
# fairy = _ConnectionRecord.checkout(pool)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 476, in checkout
# rec = pool._do_get()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\impl.py", line 145, in _do_get
# with util.safe_reraise():
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
# compat.raise_(
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\compat.py", line 208, in raise_
# raise exception
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\impl.py", line 143, in _do_get
# return self._create_connection()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 256, in _create_connection
# return _ConnectionRecord(self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 371, in __init__
# self.__connect()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 679, in __connect
# )._exec_w_sync_on_first_run(self.dbapi_connection, self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\event\attr.py", line 329, in _exec_w_sync_on_first_run
# self(*args, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\event\attr.py", line 343, in __call__
# fn(*args, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\langhelpers.py", line 1695, in go
# return once_fn(*arg, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\create.py", line 694, in first_connect
# dialect.do_rollback(c.connection)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\default.py", line 682, in do_rollback
# dbapi_connection.rollback()
# 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)')
# The above exception was the direct cause of the following exception:
# Traceback (most recent call last):
# File "synapse_issue.py", line 15, in <module>
# with engine.begin() as s_con:
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3062, in begin
# conn = self.connect(close_with_result=close_with_result)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3234, in connect
# return self._connection_cls(self, close_with_result=close_with_result)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 96, in __init__
# else engine.raw_connection()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3313, in raw_connection
# return self._wrap_pool_connect(self.pool.connect, _connection)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3283, in _wrap_pool_connect
# Connection._handle_dbapi_exception_noconnection(
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 2117, in _handle_dbapi_exception_noconnection
# util.raise_(
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\compat.py", line 208, in raise_
# raise exception
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3280, in _wrap_pool_connect
# return fn()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 310, in connect
# return _ConnectionFairy._checkout(self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 868, in _checkout
# fairy = _ConnectionRecord.checkout(pool)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 476, in checkout
# rec = pool._do_get()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\impl.py", line 145, in _do_get
# with util.safe_reraise():
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
# compat.raise_(
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\compat.py", line 208, in raise_
# raise exception
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\impl.py", line 143, in _do_get
# return self._create_connection()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 256, in _create_connection
# return _ConnectionRecord(self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 371, in __init__
# self.__connect()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 679, in __connect
# )._exec_w_sync_on_first_run(self.dbapi_connection, self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\event\attr.py", line 329, in _exec_w_sync_on_first_run
# self(*args, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\event\attr.py", line 343, in __call__
# fn(*args, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\langhelpers.py", line 1695, in go
# return once_fn(*arg, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\create.py", line 694, in first_connect
# dialect.do_rollback(c.connection)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\default.py", line 682, in do_rollback
# dbapi_connection.rollback()
# sqlalchemy.exc.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)')
# (Background on this error at: https://sqlalche.me/e/14/f405)
Error
# Traceback (most recent call last):
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3280, in _wrap_pool_connect
# return fn()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 310, in connect
# return _ConnectionFairy._checkout(self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 868, in _checkout
# fairy = _ConnectionRecord.checkout(pool)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 476, in checkout
# rec = pool._do_get()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\impl.py", line 145, in _do_get
# with util.safe_reraise():
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
# compat.raise_(
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\compat.py", line 208, in raise_
# raise exception
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\impl.py", line 143, in _do_get
# return self._create_connection()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 256, in _create_connection
# return _ConnectionRecord(self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 371, in __init__
# self.__connect()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 679, in __connect
# )._exec_w_sync_on_first_run(self.dbapi_connection, self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\event\attr.py", line 329, in _exec_w_sync_on_first_run
# self(*args, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\event\attr.py", line 343, in __call__
# fn(*args, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\langhelpers.py", line 1695, in go
# return once_fn(*arg, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\create.py", line 694, in first_connect
# dialect.do_rollback(c.connection)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\default.py", line 682, in do_rollback
# dbapi_connection.rollback()
# 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)')
# The above exception was the direct cause of the following exception:
# Traceback (most recent call last):
# File "synapse_issue.py", line 15, in <module>
# with engine.begin() as s_con:
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3062, in begin
# conn = self.connect(close_with_result=close_with_result)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3234, in connect
# return self._connection_cls(self, close_with_result=close_with_result)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 96, in __init__
# else engine.raw_connection()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3313, in raw_connection
# return self._wrap_pool_connect(self.pool.connect, _connection)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3283, in _wrap_pool_connect
# Connection._handle_dbapi_exception_noconnection(
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 2117, in _handle_dbapi_exception_noconnection
# util.raise_(
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\compat.py", line 208, in raise_
# raise exception
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\base.py", line 3280, in _wrap_pool_connect
# return fn()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 310, in connect
# return _ConnectionFairy._checkout(self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 868, in _checkout
# fairy = _ConnectionRecord.checkout(pool)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 476, in checkout
# rec = pool._do_get()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\impl.py", line 145, in _do_get
# with util.safe_reraise():
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
# compat.raise_(
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\compat.py", line 208, in raise_
# raise exception
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\impl.py", line 143, in _do_get
# return self._create_connection()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 256, in _create_connection
# return _ConnectionRecord(self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 371, in __init__
# self.__connect()
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\pool\base.py", line 679, in __connect
# )._exec_w_sync_on_first_run(self.dbapi_connection, self)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\event\attr.py", line 329, in _exec_w_sync_on_first_run
# self(*args, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\event\attr.py", line 343, in __call__
# fn(*args, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\util\langhelpers.py", line 1695, in go
# return once_fn(*arg, **kw)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\create.py", line 694, in first_connect
# dialect.do_rollback(c.connection)
# File "C:\Users\user\AppData\Roaming\Python\Python310\site-packages\sqlalchemy\engine\default.py", line 682, in do_rollback
# dbapi_connection.rollback()
# sqlalchemy.exc.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)')
# (Background on this error at: https://sqlalche.me/e/14/f405)
Versions
- OS: Windows 10
- Python: 3.10
- SQLAlchemy: 1.4.37
- Database: Azure Synapse Analytics Dedicated Pool
- DBAPI (eg: psycopg, cx_oracle, mysqlclient): pyodbc
Additional context
No response