compiler,
orm_level_statement,
dml_level_statement,
+ dml_mapper,
+ *,
use_supplemental_cols=True,
- dml_mapper=None,
):
"""establish ORM column handlers for an INSERT, UPDATE, or DELETE
which uses explicit returning().
if use_supplemental_cols:
dml_level_statement = dml_level_statement.return_defaults(
- supplemental_cols=cols_to_return
+ # this is a little weird looking, but by passing
+ # primary key as the main list of cols, this tells
+ # return_defaults to omit server-default cols. Since
+ # we have cols_to_return, just return what we asked for
+ # (plus primary key, which ORM persistence needs since
+ # we likely set bookkeeping=True here, which is another
+ # whole thing...). We dont want to clutter the
+ # statement up with lots of other cols the user didn't
+ # ask for. see #9685
+ *dml_mapper.primary_key,
+ supplemental_cols=cols_to_return,
)
else:
dml_level_statement = dml_level_statement.returning(
compiler,
orm_level_statement,
statement,
+ dml_mapper=mapper,
use_supplemental_cols=False,
)
self.statement = statement
compiler,
orm_level_statement,
statement,
- use_supplemental_cols=True,
dml_mapper=emit_insert_mapper,
+ use_supplemental_cols=True,
)
self.statement = statement
compiler,
orm_level_statement,
new_stmt,
+ dml_mapper=mapper,
use_supplemental_cols=use_supplemental_cols,
)
compiler,
orm_level_statement,
new_stmt,
+ dml_mapper=mapper,
use_supplemental_cols=use_supplemental_cols,
)
from sqlalchemy.testing.fixtures import fixture_session
-class InsertStmtTest(fixtures.TestBase):
+class InsertStmtTest(testing.AssertsExecutionResults, fixtures.TestBase):
def test_no_returning_error(self, decl_base):
class A(fixtures.ComparableEntity, decl_base):
__tablename__ = "a"
[("d3", 5), ("d4", 6)],
)
+ @testing.requires.insert_returning
+ def test_insert_returning_cols_dont_give_me_defaults(self, decl_base):
+ """test #9685"""
+
+ class User(decl_base):
+ __tablename__ = "users"
+
+ id: Mapped[int] = mapped_column(Identity(), primary_key=True)
+
+ name: Mapped[str] = mapped_column()
+ other_thing: Mapped[Optional[str]]
+ server_thing: Mapped[str] = mapped_column(server_default="thing")
+
+ decl_base.metadata.create_all(testing.db)
+ insert_stmt = insert(User).returning(User.id)
+
+ s = fixture_session()
+
+ with self.sql_execution_asserter() as asserter:
+ result = s.execute(
+ insert_stmt,
+ [
+ {"name": "some name 1"},
+ {"name": "some name 2"},
+ {"name": "some name 3"},
+ ],
+ )
+
+ eq_(result.all(), [(1,), (2,), (3,)])
+
+ asserter.assert_(
+ CompiledSQL(
+ "INSERT INTO users (name) VALUES (:name) "
+ "RETURNING users.id",
+ [
+ {"name": "some name 1"},
+ {"name": "some name 2"},
+ {"name": "some name 3"},
+ ],
+ ),
+ )
+
@testing.requires.insert_returning
def test_insert_from_select_col_property(self, decl_base):
"""test #9273"""
with self.sql_execution_asserter() as asserter:
result = s.execute(stmt, values)
- if inspect(B).single:
- single_inh = ", a.bd, a.zcol, a.q"
- else:
- single_inh = ""
-
if use_returning:
asserter.assert_(
CompiledSQL(
"INSERT INTO a (type, data, xcol) VALUES "
"(:type, :data, :xcol) "
- f"RETURNING a.id, a.type, a.data, a.xcol, a.y{single_inh}",
+ "RETURNING a.id, a.type, a.data, a.xcol, a.y",
[
{"type": "a", "data": "d3", "xcol": 5},
{"type": "a", "data": "d4", "xcol": 6},
),
CompiledSQL(
"INSERT INTO a (type, data) VALUES (:type, :data) "
- f"RETURNING a.id, a.type, a.data, a.xcol, a.y{single_inh}",
+ "RETURNING a.id, a.type, a.data, a.xcol, a.y",
[{"type": "a", "data": "d5"}],
),
CompiledSQL(
"INSERT INTO a (type, data, xcol, y) "
"VALUES (:type, :data, :xcol, :y) "
- f"RETURNING a.id, a.type, a.data, a.xcol, a.y{single_inh}",
+ "RETURNING a.id, a.type, a.data, a.xcol, a.y",
[
{"type": "a", "data": "d6", "xcol": 8, "y": 9},
{"type": "a", "data": "d7", "xcol": 12, "y": 12},
CompiledSQL(
"INSERT INTO a (type, data, xcol) "
"VALUES (:type, :data, :xcol) "
- f"RETURNING a.id, a.type, a.data, a.xcol, a.y{single_inh}",
+ "RETURNING a.id, a.type, a.data, a.xcol, a.y",
[{"type": "a", "data": "d8", "xcol": 7}],
),
)
)
if use_returning:
- eq_(
- result.scalars().all(),
- [
- A(data="d3", id=mock.ANY, type="a", x=5, y=None),
- A(data="d4", id=mock.ANY, type="a", x=6, y=None),
- A(data="d5", id=mock.ANY, type="a", x=None, y=None),
- A(data="d6", id=mock.ANY, type="a", x=8, y=9),
- A(data="d7", id=mock.ANY, type="a", x=12, y=12),
- A(data="d8", id=mock.ANY, type="a", x=7, y=None),
- ],
- )
+ with self.assert_statement_count(testing.db, 0):
+ eq_(
+ result.scalars().all(),
+ [
+ A(data="d3", id=mock.ANY, type="a", x=5, y=None),
+ A(data="d4", id=mock.ANY, type="a", x=6, y=None),
+ A(data="d5", id=mock.ANY, type="a", x=None, y=None),
+ A(data="d6", id=mock.ANY, type="a", x=8, y=9),
+ A(data="d7", id=mock.ANY, type="a", x=12, y=12),
+ A(data="d8", id=mock.ANY, type="a", x=7, y=None),
+ ],
+ )
@testing.combinations(
"strings",