[Sqlalchemy-tickets] Issue #3169: _fetch_implicit_returning raises TypeError if INSERT FROM SELECT
Brought to you by:
zzzeek
|
From: Richard F. <iss...@bi...> - 2014-08-20 21:55:11
|
New issue 3169: _fetch_implicit_returning raises TypeError if INSERT FROM SELECT inserts no rows https://bitbucket.org/zzzeek/sqlalchemy/issue/3169/_fetch_implicit_returning-raises-typeerror Richard Frank: I'm inserting into a table using the results of a query. When that query returns no rows, a TypeError is raised. A test example: ``` #!python from sqlalchemy import create_engine, String, Column, Table, MetaData, \ literal_column, select engine = create_engine('postgresql://rich@localhost/test', echo=True) metadata = MetaData() with engine.connect() as conn: tbl = Table('test_table', metadata, Column('id', String, primary_key=True)) tbl.create(bind=conn) conn.execute( tbl.insert() .from_select( [tbl.c.id], select([literal_column("'id'")]) .where(literal_column("false"))) ) ``` dies with the following error on 0.9.7 with psycopg2 2.5.3 and postgresql 9.3.4: ``` #!python 2014-08-20 17:34:19,054 INFO sqlalchemy.engine.base.Engine select version() 2014-08-20 17:34:19,054 INFO sqlalchemy.engine.base.Engine {} 2014-08-20 17:34:19,057 INFO sqlalchemy.engine.base.Engine select current_schema() 2014-08-20 17:34:19,057 INFO sqlalchemy.engine.base.Engine {} 2014-08-20 17:34:19,058 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 2014-08-20 17:34:19,058 INFO sqlalchemy.engine.base.Engine {} 2014-08-20 17:34:19,059 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 2014-08-20 17:34:19,059 INFO sqlalchemy.engine.base.Engine {} 2014-08-20 17:34:19,060 INFO sqlalchemy.engine.base.Engine show standard_conforming_strings 2014-08-20 17:34:19,060 INFO sqlalchemy.engine.base.Engine {} 2014-08-20 17:34:19,062 INFO sqlalchemy.engine.base.Engine CREATE TABLE test_table ( id VARCHAR NOT NULL, PRIMARY KEY (id) ) 2014-08-20 17:34:19,062 INFO sqlalchemy.engine.base.Engine {} 2014-08-20 17:34:19,069 INFO sqlalchemy.engine.base.Engine COMMIT 2014-08-20 17:34:19,071 INFO sqlalchemy.engine.base.Engine INSERT INTO test_table (id) SELECT 'id' WHERE false RETURNING test_table.id 2014-08-20 17:34:19,071 INFO sqlalchemy.engine.base.Engine {} Traceback (most recent call last): File "test.py", line 19, in <module> .where(literal_column("false"))) File "/Users/rich/.virtualenvs/test/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 729, in execute return meth(self, multiparams, params) File "/Users/rich/.virtualenvs/test/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 321, in _execute_on_connection return connection._execute_clauseelement(self, multiparams, params) File "/Users/rich/.virtualenvs/test/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 826, in _execute_clauseelement compiled_sql, distilled_params File "/Users/rich/.virtualenvs/test/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 978, in _execute_context context._fetch_implicit_returning(result) File "/Users/rich/.virtualenvs/test/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 815, in _fetch_implicit_returning ipk.append(row[c]) TypeError: 'NoneType' object has no attribute '__getitem__' ``` Assuming that functionality isn't needed, looks like this can be worked around by setting ```implicit_returning=False``` on the engine or table. |