diff --git a/src/datajoint/table.py b/src/datajoint/table.py index 7543c385e..6b45ecf04 100644 --- a/src/datajoint/table.py +++ b/src/datajoint/table.py @@ -148,8 +148,15 @@ def declare(self, context=None): try: self.connection.query(sql) except AccessError: - # skip if no create privilege - return + # Only suppress if table already exists (idempotent declaration) + # Otherwise raise - user needs to know about permission issues + if self.is_declared: + return + raise AccessError( + f"Cannot declare table {self.full_table_name}. " + f"Check that you have CREATE privilege on schema `{self.database}` " + f"and REFERENCES privilege on any referenced parent tables." + ) from None # Populate lineage table for this table's attributes self._populate_lineage(primary_key, fk_attribute_map) diff --git a/tests/integration/test_privileges.py b/tests/integration/test_privileges.py index ff5fc0c7f..0939823a0 100644 --- a/tests/integration/test_privileges.py +++ b/tests/integration/test_privileges.py @@ -90,18 +90,19 @@ def test_insert_failure(self, connection_djview, schema_any): UnprivilegedLanguage().insert1(("Socrates", "Greek")) def test_failure_to_create_table(self, connection_djview, schema_any): + """Table declaration should raise AccessError when user lacks CREATE privilege.""" unprivileged = dj.Schema(schema_any.database, namespace, connection=connection_djview) - @unprivileged - class Try(dj.Manual): - definition = """ # should not matter really - id : int - --- - value : float - """ + # Should raise AccessError at declaration time, not silently fail + with pytest.raises(dj.errors.AccessError): - with pytest.raises(dj.DataJointError): - Try().insert1((1, 1.5)) + @unprivileged + class Try(dj.Manual): + definition = """ # should not matter really + id : int + --- + value : float + """ class TestSubset: