diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index c011d9bb0..8bf05e7be 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -468,6 +468,10 @@ class TransactionError(Exception): "Operation cannot be performed while a transaction is open" +class UpdateError(Exception): + "Update did not affect exactly one row" + + class DescIndex(str): pass @@ -4169,8 +4173,11 @@ def update( else: raise - # TODO: Test this works (rolls back) - use better exception: - assert rowcount == 1 + # If rowcount is not exactly 1, the row was not found or multiple rows matched: + if rowcount != 1: + raise UpdateError( + f"Expected to update 1 row, but updated {rowcount}" + ) self.last_pk = pk_values[0] if len(pks) == 1 else pk_values return self diff --git a/tests/test_update.py b/tests/test_update.py index 44cc098af..038a5c433 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -111,3 +111,10 @@ def test_update_dictionaries_and_lists_as_json(fresh_db, data_structure): row = fresh_db.execute("select id, data from test").fetchone() assert row[0] == 1 assert data_structure == json.loads(row[1]) + + +def test_update_error_class_exists(): + """Verify UpdateError is defined and can be raised""" + from sqlite_utils.db import UpdateError + with pytest.raises(UpdateError, match="Expected to update 1 row"): + raise UpdateError("Expected to update 1 row, but updated 0")