Skip to content

Commit c2a2eae

Browse files
refactor: improve API consistency for jobs and schema.drop
AutoPopulate.jobs: - Changed from @Property to descriptor pattern - Now accessible on both class and instance: Analysis.jobs.refresh() # class access Analysis().jobs.refresh() # instance access - Maintains lazy initialization behavior Schema.drop(): - Changed parameter from `force` to `prompt` for clarity - prompt=True: show confirmation prompt - prompt=False: drop without confirmation - prompt=None (default): use dj.config['safemode'] setting - More intuitive: prompt=False means "don't prompt" vs force=True which meant "force without prompt" Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 9737dee commit c2a2eae

File tree

2 files changed

+39
-26
lines changed

2 files changed

+39
-26
lines changed

src/datajoint/autopopulate.py

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -93,27 +93,40 @@ class AutoPopulate:
9393
_allow_insert = False
9494
_jobs = None
9595

96-
@property
97-
def jobs(self) -> Job:
98-
"""
99-
Access the job table for this auto-populated table.
96+
class _JobsDescriptor:
97+
"""Descriptor allowing jobs access on both class and instance."""
10098

101-
The job table (``~~table_name``) is created lazily on first access.
102-
It tracks job status, priority, scheduling, and error information
103-
for distributed populate operations.
99+
def __get__(self, obj, objtype=None):
100+
"""
101+
Access the job table for this auto-populated table.
104102
105-
Returns
106-
-------
107-
Job
108-
Job management object for this table.
109-
"""
110-
if self._jobs is None:
111-
from .jobs import Job
103+
The job table (``~~table_name``) is created lazily on first access.
104+
It tracks job status, priority, scheduling, and error information
105+
for distributed populate operations.
106+
107+
Can be accessed on either the class or an instance::
112108
113-
self._jobs = Job(self)
114-
if not self._jobs.is_declared:
115-
self._jobs.declare()
116-
return self._jobs
109+
# Both work equivalently
110+
Analysis.jobs.refresh()
111+
Analysis().jobs.refresh()
112+
113+
Returns
114+
-------
115+
Job
116+
Job management object for this table.
117+
"""
118+
if obj is None:
119+
# Accessed on class - instantiate first
120+
obj = objtype()
121+
if obj._jobs is None:
122+
from .jobs import Job
123+
124+
obj._jobs = Job(obj)
125+
if not obj._jobs.is_declared:
126+
obj._jobs.declare()
127+
return obj._jobs
128+
129+
jobs: Job = _JobsDescriptor()
117130

118131
def _declare_check(self, primary_key: list[str], fk_attribute_map: dict[str, tuple[str, str]]) -> None:
119132
"""

src/datajoint/schemas.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -390,27 +390,27 @@ def spawn_missing_classes(self, context: dict[str, Any] | None = None) -> None:
390390
self._decorate_table(part_class, context=context, assert_declared=True)
391391
setattr(master_class, class_name, part_class)
392392

393-
def drop(self, force: bool = False) -> None:
393+
def drop(self, prompt: bool | None = None) -> None:
394394
"""
395395
Drop the associated schema and all its tables.
396396
397397
Parameters
398398
----------
399-
force : bool, optional
400-
If True, skip confirmation prompt. Default False.
399+
prompt : bool, optional
400+
If True, show confirmation prompt before dropping.
401+
If False, drop without confirmation.
402+
If None (default), use ``dj.config['safemode']`` setting.
401403
402404
Raises
403405
------
404406
AccessError
405407
If insufficient permissions to drop the schema.
406408
"""
409+
prompt = config["safemode"] if prompt is None else prompt
410+
407411
if not self.exists:
408412
logger.info("Schema named `{database}` does not exist. Doing nothing.".format(database=self.database))
409-
elif (
410-
not config["safemode"]
411-
or force
412-
or user_choice("Proceed to delete entire schema `%s`?" % self.database, default="no") == "yes"
413-
):
413+
elif not prompt or user_choice("Proceed to delete entire schema `%s`?" % self.database, default="no") == "yes":
414414
logger.debug("Dropping `{database}`.".format(database=self.database))
415415
try:
416416
self.connection.query("DROP DATABASE `{database}`".format(database=self.database))

0 commit comments

Comments
 (0)