diff --git a/CHANGELOG.md b/CHANGELOG.md index e107b29bb..a1615ccd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## Release notes +### Upcoming +- Fixed - Fix altering a part table that uses the "master" keyword - PR [#991](https://github.com/datajoint/datajoint-python/pull/991) + ### 0.14.0 -- Feb 13, 2023 - Added - `json` data type ([#245](https://github.com/datajoint/datajoint-python/issues/245)) PR [#1051](https://github.com/datajoint/datajoint-python/pull/1051) - Fixed - Activating a schema requires all tables to exist even if `create_tables=False` PR [#1058](https://github.com/datajoint/datajoint-python/pull/1058) diff --git a/datajoint/user_tables.py b/datajoint/user_tables.py index 16084631f..bcb6a0277 100644 --- a/datajoint/user_tables.py +++ b/datajoint/user_tables.py @@ -238,3 +238,7 @@ def drop(self, force=False): raise DataJointError( "Cannot drop a Part directly. Delete from master instead" ) + + def alter(self, prompt=True, context=None): + # without context, use declaration context which maps master keyword to master table + super().alter(prompt=prompt, context=context or self.declaration_context) diff --git a/tests/test_alter.py b/tests/test_alter.py index a785ffa28..f5fdf942c 100644 --- a/tests/test_alter.py +++ b/tests/test_alter.py @@ -1,4 +1,5 @@ from nose.tools import assert_equal, assert_not_equal +import re from .schema import * @@ -27,6 +28,33 @@ class Experiment(dj.Imported): """ +@schema +class Parent(dj.Manual): + definition = """ + parent_id: int + """ + + class Child(dj.Part): + definition = """ + -> Parent + """ + definition_new = """ + -> master + --- + child_id=null: int + """ + + class Grandchild(dj.Part): + definition = """ + -> master.Child + """ + definition_new = """ + -> master.Child + --- + grandchild_id=null: int + """ + + def test_alter(): original = schema.connection.query( "SHOW CREATE TABLE " + Experiment.full_table_name @@ -44,3 +72,25 @@ def test_alter(): ).fetchone()[1] assert_not_equal(altered, restored) assert_equal(original, restored) + + +def test_alter_part(): + # https://github.com/datajoint/datajoint-python/issues/936 + + def verify_alter(table, attribute_sql): + definition_original = schema.connection.query( + f"SHOW CREATE TABLE {table.full_table_name}" + ).fetchone()[1] + table.definition = table.definition_new + table.alter(prompt=False) + definition_new = schema.connection.query( + f"SHOW CREATE TABLE {table.full_table_name}" + ).fetchone()[1] + assert ( + re.sub(f"{attribute_sql},\n ", "", definition_new) == definition_original + ) + + verify_alter(table=Parent.Child, attribute_sql="`child_id` .* DEFAULT NULL") + verify_alter( + table=Parent.Grandchild, attribute_sql="`grandchild_id` .* DEFAULT NULL" + )