From 90524929659f6d132ae3230e984d213f787df29a Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 25 Dec 2025 03:25:47 +0000 Subject: [PATCH 1/2] Allow Part.delete to pass kwargs through to Table.delete Enable users to pass keyword arguments like transaction=False to Part.delete, which are then forwarded to the parent Table.delete method. This allows wrapping Part.delete in external transactions. Fixes #1276 Co-authored-by: dimitri-yatsenko --- src/datajoint/user_tables.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/datajoint/user_tables.py b/src/datajoint/user_tables.py index 59065e7f1..59028806d 100644 --- a/src/datajoint/user_tables.py +++ b/src/datajoint/user_tables.py @@ -220,12 +220,22 @@ def master(cls): def table_name(cls): return None if cls.master is None else cls.master.table_name + "__" + from_camel_case(cls.__name__) - def delete(self, force=False): + def delete(self, force=False, **kwargs): """ - unless force is True, prohibits direct deletes from parts. + Delete contents of a Part table. + + Unless force is True, prohibits direct deletes from parts. + + Args: + force: If True, allow direct deletion from this Part table. + **kwargs: Additional keyword arguments passed to Table.delete(), + such as transaction, safemode, and force_masters. + + Raises: + DataJointError: If force is False (default). """ if force: - super().delete(force_parts=True) + super().delete(force_parts=True, **kwargs) else: raise DataJointError("Cannot delete from a Part directly. Delete from master instead") From 5e40c87f12ccd0c23d8f77648e1e2be330f877fe Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 25 Dec 2025 03:27:28 +0000 Subject: [PATCH 2/2] Add test for Part.delete kwargs pass-through Verify that kwargs like transaction=False can be passed to Part.delete and forwarded to Table.delete, enabling use within external transactions. Tests #1276 Co-authored-by: dimitri-yatsenko --- tests/test_cascading_delete.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_cascading_delete.py b/tests/test_cascading_delete.py index 31499d11b..bf52d08c8 100644 --- a/tests/test_cascading_delete.py +++ b/tests/test_cascading_delete.py @@ -146,3 +146,23 @@ def test_delete_1159(thing_tables): assert len(tbl_a) == 6, "Failed to cascade restriction attributes" assert len(tbl_e) == 3, "Failed to cascade restriction attributes" + + +def test_part_delete_kwargs_passthrough(schema_simp_pop): + """Test issue #1276: Part.delete should pass kwargs through to Table.delete. + + This test verifies that kwargs like transaction=False can be passed to + Part.delete, enabling use within external transactions. + """ + assert B.C(), "Part table B.C should have data" + initial_count = len(B.C()) + + # Use an external transaction and pass transaction=False to Part.delete + with B.C().connection.transaction: + # Restrict to a single entry and delete with transaction=False + restricted = B.C() & "id_a=0 AND id_b=0 AND id_c=0" + if restricted: + restricted.delete(force=True, transaction=False) + + # Verify deletion occurred + assert len(B.C()) < initial_count, "Part.delete with transaction=False should work"