From: Mike Bayer Date: Wed, 21 Dec 2016 18:39:56 +0000 (-0500) Subject: Call nextval() on sequence when doing INSERT from SELECT X-Git-Tag: rel_1_1_5~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5bb919aa6d5b9961f85987dfaa58d5999910d15;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Call nextval() on sequence when doing INSERT from SELECT Fixed bug where an INSERT from SELECT where the source table contains an autoincrementing Sequence would fail to compile correctly. Change-Id: I41eb9f65789a4007712ae61ed5fa23a9839a5128 Fixes: #3877 --- diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst index 2314a621d2..6b842ab077 100644 --- a/doc/build/changelog/changelog_11.rst +++ b/doc/build/changelog/changelog_11.rst @@ -21,6 +21,13 @@ .. changelog:: :version: 1.1.5 + .. change:: 3877 + :tags: bug, oracle, postgresql + :tickets: 3877 + + Fixed bug where an INSERT from SELECT where the source table contains + an autoincrementing Sequence would fail to compile correctly. + .. change:: 3875 :tags: bug, oracle :tickets: 3875 diff --git a/lib/sqlalchemy/sql/crud.py b/lib/sqlalchemy/sql/crud.py index 9d10fbefc0..9808b7d90f 100644 --- a/lib/sqlalchemy/sql/crud.py +++ b/lib/sqlalchemy/sql/crud.py @@ -505,7 +505,7 @@ def _append_param_insert_select_hasdefault( (not c.default.optional or not compiler.dialect.sequences_optional): proc = c.default - values.append((c, proc)) + values.append((c, proc.next_value())) elif c.default.is_clause_element: proc = c.default.arg.self_group() values.append((c, proc)) diff --git a/test/sql/test_insert.py b/test/sql/test_insert.py index 2fa1860de6..73731e9527 100644 --- a/test/sql/test_insert.py +++ b/test/sql/test_insert.py @@ -1,7 +1,8 @@ #! coding:utf-8 from sqlalchemy import Column, Integer, MetaData, String, Table,\ - bindparam, exc, func, insert, select, column, text, table + bindparam, exc, func, insert, select, column, text, table,\ + Sequence from sqlalchemy.dialects import mysql, postgresql from sqlalchemy.engine import default from sqlalchemy.testing import AssertsCompiledSQL,\ @@ -238,6 +239,24 @@ class InsertTest(_InsertTestBase, fixtures.TablesTest, AssertsCompiledSQL): checkparams={"name_1": "foo"} ) + def test_insert_from_select_seq(self): + m = MetaData() + + t1 = Table( + 't', m, + Column('id', Integer, Sequence('id_seq'), primary_key=True), + Column('data', String) + ) + + stmt = t1.insert().from_select(('data', ), select([t1.c.data])) + + self.assert_compile( + stmt, + "INSERT INTO t (data, id) SELECT t.data, " + "nextval('id_seq') AS next_value_1 FROM t", + dialect=postgresql.dialect() + ) + def test_insert_from_select_cte_one(self): table1 = self.tables.mytable