diff --git a/CHANGELOG.md b/CHANGELOG.md index a64ca378..1a7b8603 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,15 @@ ## Release notes -### 0.14.3 -- Sep 20, 2024 -- Added - `dj.Top` restriction ([#1024](https://github.com/datajoint/datajoint-python/issues/1024)) PR [#1084](https://github.com/datajoint/datajoint-python/pull/1084) +### 0.14.3 -- Sep 23, 2024 +- Added - `dj.Top` restriction - PR [#1024](https://github.com/datajoint/datajoint-python/issues/1024)) PR [#1084](https://github.com/datajoint/datajoint-python/pull/1084) - Fixed - Added encapsulating double quotes to comply with [DOT language](https://graphviz.org/doc/info/lang.html) - PR [#1177](https://github.com/datajoint/datajoint-python/pull/1177) -- Added - Datajoint python CLI ([#940](https://github.com/datajoint/datajoint-python/issues/940)) PR [#1095](https://github.com/datajoint/datajoint-python/pull/1095) +- Added - Datajoint python CLI ([#940](https://github.com/datajoint/datajoint-python/issues/940)) - PR [#1095](https://github.com/datajoint/datajoint-python/pull/1095) - Added - Ability to set hidden attributes on a table - PR [#1091](https://github.com/datajoint/datajoint-python/pull/1091) - Added - Ability to specify a list of keys to populate - PR [#989](https://github.com/datajoint/datajoint-python/pull/989) -- Fixed - fixed topological sort [#1057](https://github.com/datajoint/datajoint-python/issues/1057)- PR [#1184](https://github.com/datajoint/datajoint-python/pull/1184) -- Fixed - .parts() not always returning parts [#1103](https://github.com/datajoint/datajoint-python/issues/1103)- PR [#1184](https://github.com/datajoint/datajoint-python/pull/1184) -- Changed - replace `setup.py` with `pyproject.toml` PR [#1183](https://github.com/datajoint/datajoint-python/pull/1183) +- Fixed - fixed topological sort [#1057](https://github.com/datajoint/datajoint-python/issues/1057) - PR [#1184](https://github.com/datajoint/datajoint-python/pull/1184) +- Fixed - .parts() not always returning parts [#1103](https://github.com/datajoint/datajoint-python/issues/1103) - PR [#1184](https://github.com/datajoint/datajoint-python/pull/1184) +- Changed - replace `setup.py` with `pyproject.toml` - PR [#1183](https://github.com/datajoint/datajoint-python/pull/1183) +- Changed - disable `add_hidden_timestamp` configuration option by default - PR [#1188](https://github.com/datajoint/datajoint-python/pull/1188) ### 0.14.2 -- Aug 19, 2024 - Added - Migrate nosetests to pytest - PR [#1142](https://github.com/datajoint/datajoint-python/pull/1142) diff --git a/datajoint/declare.py b/datajoint/declare.py index 1c02564a..b1194880 100644 --- a/datajoint/declare.py +++ b/datajoint/declare.py @@ -10,6 +10,7 @@ from .errors import DataJointError, _support_filepath_types, FILEPATH_FEATURE_SWITCH from .attribute_adapter import get_adapter from .condition import translate_attribute +from .settings import config UUID_DATA_TYPE = "binary(16)" MAX_TABLE_NAME_LENGTH = 64 @@ -311,17 +312,18 @@ def declare(full_table_name, definition, context): external_stores, ) = prepare_declare(definition, context) - metadata_attr_sql = [ - "`_{full_table_name}_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP" - ] - attribute_sql.extend( - attr.format( - full_table_name=sha1( - full_table_name.replace("`", "").encode("utf-8") - ).hexdigest() + if config.get("add_hidden_timestamp", False): + metadata_attr_sql = [ + "`_{full_table_name}_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP" + ] + attribute_sql.extend( + attr.format( + full_table_name=sha1( + full_table_name.replace("`", "").encode("utf-8") + ).hexdigest() + ) + for attr in metadata_attr_sql ) - for attr in metadata_attr_sql - ) if not primary_key: raise DataJointError("Table must have a primary key") diff --git a/datajoint/settings.py b/datajoint/settings.py index 4fc7f301..cdf27891 100644 --- a/datajoint/settings.py +++ b/datajoint/settings.py @@ -47,6 +47,7 @@ "display.show_tuple_count": True, "database.use_tls": None, "enable_python_native_blobs": True, # python-native/dj0 encoding support + "add_hidden_timestamp": False, "filepath_checksum_size_limit": None, # file size limit for when to disable checksums } ) diff --git a/tests/test_declare.py b/tests/test_declare.py index f848d31c..b3c92829 100644 --- a/tests/test_declare.py +++ b/tests/test_declare.py @@ -3,6 +3,25 @@ import datajoint as dj import inspect from datajoint.declare import declare +from datajoint.settings import config + + +@pytest.fixture(scope="function") +def enable_add_hidden_timestamp(): + orig_config_val = config.get("add_hidden_timestamp") + config["add_hidden_timestamp"] = True + yield + if orig_config_val is not None: + config["add_hidden_timestamp"] = orig_config_val + + +@pytest.fixture(scope="function") +def disable_add_hidden_timestamp(): + orig_config_val = config.get("add_hidden_timestamp") + config["add_hidden_timestamp"] = False + yield + if orig_config_val is not None: + config["add_hidden_timestamp"] = orig_config_val def test_schema_decorator(schema_any): @@ -373,9 +392,36 @@ class Table_With_Underscores(dj.Manual): schema_any(Table_With_Underscores) -def test_hidden_attributes(schema_any): +def test_add_hidden_timestamp_default_value(): + config_val = config.get("add_hidden_timestamp") assert ( - list(Experiment().heading._attributes.keys())[-1].split("_")[2] == "timestamp" - ) - assert any(a.is_hidden for a in Experiment().heading._attributes.values()) - assert not any(a.is_hidden for a in Experiment().heading.attributes.values()) + config_val is not None and not config_val + ), "Default value for add_hidden_timestamp is not False" + + +def test_add_hidden_timestamp_enabled(enable_add_hidden_timestamp, schema_any): + assert config["add_hidden_timestamp"], "add_hidden_timestamp is not enabled" + msg = f"{Experiment().heading._attributes=}" + assert any( + a.name.endswith("_timestamp") for a in Experiment().heading._attributes.values() + ), msg + assert any( + a.name.startswith("_") for a in Experiment().heading._attributes.values() + ), msg + assert any(a.is_hidden for a in Experiment().heading._attributes.values()), msg + assert not any(a.is_hidden for a in Experiment().heading.attributes.values()), msg + + +def test_add_hidden_timestamp_disabled(disable_add_hidden_timestamp, schema_any): + assert not config[ + "add_hidden_timestamp" + ], "expected add_hidden_timestamp to be False" + msg = f"{Experiment().heading._attributes=}" + assert not any( + a.name.endswith("_timestamp") for a in Experiment().heading._attributes.values() + ), msg + assert not any( + a.name.startswith("_") for a in Experiment().heading._attributes.values() + ), msg + assert not any(a.is_hidden for a in Experiment().heading._attributes.values()), msg + assert not any(a.is_hidden for a in Experiment().heading.attributes.values()), msg