summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/orm/session_basics.rst8
-rw-r--r--doc/build/tutorial/data.rst2
-rw-r--r--lib/sqlalchemy/engine/cursor.py7
-rw-r--r--test/orm/test_update_delete.py11
4 files changed, 22 insertions, 6 deletions
diff --git a/doc/build/orm/session_basics.rst b/doc/build/orm/session_basics.rst
index 0ea797fa9..a5620ef6e 100644
--- a/doc/build/orm/session_basics.rst
+++ b/doc/build/orm/session_basics.rst
@@ -559,11 +559,17 @@ Core :class:`_sql.Update` construct::
stmt = update(User).where(User.name == "squidward").values(name="spongebob").\
execution_options(synchronize_session="fetch")
- session.execute(stmt)
+ result = session.execute(stmt)
Above, the :meth:`_dml.Update.execution_options` method may be used to
establish execution-time options such as "synchronize_session".
+The result object returned is an instance of :class:`_result.CursorResult`; to
+retrieve the number of rows matched by any UPDATE or DELETE statement, use
+:attr:`_result.CursorResult.rowcount`::
+
+ num_rows_matched = result.rowcount
+
DELETEs work in the same way as UPDATE except there is no "values / set"
clause established. When synchronize_session is used, matching objects
within the :class:`_orm.Session` will be marked as deleted and expunged.
diff --git a/doc/build/tutorial/data.rst b/doc/build/tutorial/data.rst
index a658a7db7..f5009df58 100644
--- a/doc/build/tutorial/data.rst
+++ b/doc/build/tutorial/data.rst
@@ -1933,6 +1933,8 @@ syntaxes, such as ``DELETE FROM..USING`` on MySQL::
{opensql}DELETE FROM user_account USING user_account, address
WHERE user_account.id = address.user_id AND address.email_address = %s
+.. _tutorial_update_delete_rowcount:
+
Getting Affected Row Count from UPDATE, DELETE
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/lib/sqlalchemy/engine/cursor.py b/lib/sqlalchemy/engine/cursor.py
index 5a3b92901..24a7cdb80 100644
--- a/lib/sqlalchemy/engine/cursor.py
+++ b/lib/sqlalchemy/engine/cursor.py
@@ -1620,7 +1620,12 @@ class BaseCursorResult(object):
* Statements that use RETURNING may not return a correct
rowcount.
- """
+ .. seealso::
+
+ :ref:`tutorial_update_delete_rowcount` - in the :ref:`unified_tutorial`
+
+ """ # noqa E501
+
try:
return self.context.rowcount
except BaseException as e:
diff --git a/test/orm/test_update_delete.py b/test/orm/test_update_delete.py
index c9248b118..7586a1e2e 100644
--- a/test/orm/test_update_delete.py
+++ b/test/orm/test_update_delete.py
@@ -618,25 +618,27 @@ class UpdateDeleteTest(fixtures.MappedTest):
sess.execute(select(User).order_by(User.id)).scalars().all()
)
- sess.execute(
+ result = sess.execute(
update(User)
.where(User.age > 29)
.values({"age": User.age - 10})
.execution_options(synchronize_session="evaluate"),
)
+ eq_(result.rowcount, 2)
eq_([john.age, jack.age, jill.age, jane.age], [25, 37, 29, 27])
eq_(
sess.execute(select(User.age).order_by(User.id)).all(),
list(zip([25, 37, 29, 27])),
)
- sess.execute(
+ result = sess.execute(
update(User)
.where(User.age > 29)
.values({User.age: User.age - 10})
- .execution_options(synchronize_session="evaluate")
+ .execution_options(synchronize_session="fetch")
)
+ eq_(result.rowcount, 1)
eq_([john.age, jack.age, jill.age, jane.age], [25, 27, 29, 27])
eq_(
sess.query(User.age).order_by(User.id).all(),
@@ -874,10 +876,11 @@ class UpdateDeleteTest(fixtures.MappedTest):
.where(User.age > 29)
.values({"age": User.age - 10})
)
- sess.execute(
+ result = sess.execute(
stmt, execution_options={"synchronize_session": "fetch"}
)
+ eq_(result.rowcount, 2)
# these are simple values, these are now evaluated even with
# the "fetch" strategy, new in 1.4, so there is no expiry
eq_([john.age, jack.age, jill.age, jane.age], [25, 37, 29, 27])