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") 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"