Hello everyone,

I encountered a surprising behavior of the postres specific insert when 
using UniqueConstraint.

A test code :

from sqlalchemy import Column, Integer, String, UniqueConstraint, 
create_engine
from sqlalchemy.dialects.postgresql import insert as pg_insert
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class TestClass(Base):
    __tablename__ = 'test'
    id_ = Column('id_', Integer, primary_key=True)
    a = Column('a', Integer)
    b = Column('b', String)
    __table_args__ = (UniqueConstraint('a', 'b', name='const'),)

engine = create_engine('mysql+mysqldb://db_user:db_pswd@db_host/db_name')
TestClass.metadata.create_all(engine)
query = pg_insert(TestClass).values(a=1, b='b').on_conflict_do_nothing(
constraint='const')
engine.execute(query)
engine.execute(query)





The exception returned :


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in connection(self)
    345         try:
--> 346             return self.__connection
    347         except AttributeError:

AttributeError: 'Connection' object has no attribute 
'_Connection__connection'

During handling of the above exception, another exception occurred:

ResourceClosedError                       Traceback (most recent call last)
/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in _commit_impl(self, autocommit)
    722         except BaseException as e:
--> 723             self._handle_dbapi_exception(e, None, None, None, None)
    724         finally:

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
   1396             else:
-> 1397                 util.reraise(*exc_info)
   1398 

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/util/compat.py 
in reraise(tp, value, tb, cause)
    186             raise value.with_traceback(tb)
--> 187         raise value
    188 

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in _commit_impl(self, autocommit)
    720         try:
--> 721             self.engine.dialect.do_commit(self.connection)
    722         except BaseException as e:

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in connection(self)
    350             except BaseException as e:
--> 351                 self._handle_dbapi_exception(e, None, None, None, 
None)
    352 

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
   1396             else:
-> 1397                 util.reraise(*exc_info)
   1398 

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/util/compat.py 
in reraise(tp, value, tb, cause)
    186             raise value.with_traceback(tb)
--> 187         raise value
    188 

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in connection(self)
    348             try:
--> 349                 return self._revalidate_connection()
    350             except BaseException as e:

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in _revalidate_connection(self)
    428             return self.__connection
--> 429         raise exc.ResourceClosedError("This Connection is closed")
    430 

ResourceClosedError: This Connection is closed

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in connection(self)
    345         try:
--> 346             return self.__connection
    347         except AttributeError:

AttributeError: 'Connection' object has no attribute 
'_Connection__connection'

During handling of the above exception, another exception occurred:

ResourceClosedError                       Traceback (most recent call last)
<ipython-input-2-02fbc1f7d6d4> in <module>()
     14 TestClass.metadata.create_all(engine)
     15 query = pg_insert(TestClass).values(a=1, b='b').
on_conflict_do_nothing(constraint='const1')
---> 16 engine.execute(query)
     17 engine.execute(query)

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in execute(self, statement, *multiparams, **params)
   2054 
   2055         connection = self.contextual_connect(close_with_result=True)
-> 2056         return connection.execute(statement, *multiparams, **params)
   2057 
   2058     def scalar(self, statement, *multiparams, **params):

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in execute(self, object, *multiparams, **params)
    943             raise exc.ObjectNotExecutableError(object)
    944         else:
--> 945             return meth(self, multiparams, params)
    946 
    947     def _execute_function(self, func, multiparams, params):

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/sql/elements.py 
in _execute_on_connection(self, connection, multiparams, params)
    261     def _execute_on_connection(self, connection, multiparams, params
):
    262         if self.supports_execution:
--> 263             return connection._execute_clauseelement(self, 
multiparams, params)
    264         else:
    265             raise exc.ObjectNotExecutableError(self)

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in _execute_clauseelement(self, elem, multiparams, params)
   1051             compiled_sql,
   1052             distilled_params,
-> 1053             compiled_sql, distilled_params
   1054         )
   1055         if self._has_events or self.engine._has_events:

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in _execute_context(self, dialect, constructor, statement, parameters, *args
)
   1207 
   1208         if context.should_autocommit and self._root.__transaction is 
None:
-> 1209             self._root._commit_impl(autocommit=True)
   1210 
   1211         if result._soft_closed and self.should_close_with_result:

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in _commit_impl(self, autocommit)
    724         finally:
    725             if not self.__invalid and \
--> 726                     self.connection._reset_agent is self.
__transaction:
    727                 self.connection._reset_agent = None
    728             self.__transaction = None

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in connection(self)
    349                 return self._revalidate_connection()
    350             except BaseException as e:
--> 351                 self._handle_dbapi_exception(e, None, None, None, 
None)
    352 
    353     def get_isolation_level(self):

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
   1395                 )
   1396             else:
-> 1397                 util.reraise(*exc_info)
   1398 
   1399         finally:

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/util/compat.py 
in reraise(tp, value, tb, cause)
    185         if value.__traceback__ is not tb:
    186             raise value.with_traceback(tb)
--> 187         raise value
    188 
    189 else:

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in connection(self)
    347         except AttributeError:
    348             try:
--> 349                 return self._revalidate_connection()
    350             except BaseException as e:
    351                 self._handle_dbapi_exception(e, None, None, None, 
None)

/home/test/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py 
in _revalidate_connection(self)
    427             self.__invalid = False
    428             return self.__connection
--> 429         raise exc.ResourceClosedError("This Connection is closed")
    430 
    431     @property

ResourceClosedError: This Connection is close



I guess I did something wrong, but the error message seems completely 
unrelated to the operation (A RessourceClosed error ?).
It is to note that it is the second execution of the query (or the first 
execution on a table with the line from query already present) that raise 
this exception.

The exception is not raised when we put a value to id_ (for example 
values(a=1, b='b', id=1) ).

It was done with sqlalchemy 1.1.8 and postgres 9.6.2.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to