Skip to content

Commit 02bbba6

Browse files
feat: Add backward-compatible fetch() with deprecation warning
Restore fetch() method for easier migration from DataJoint 0.14. The method emits a DeprecationWarning and maps to 2.0 methods: - fetch() → to_arrays() - fetch(as_dict=True) → to_dicts() - fetch('col1', 'col2') → proj(...).to_dicts() - fetch('col1', 'col2', as_dict=False) → to_arrays('col1', 'col2') - fetch(format='frame') → to_pandas() Supports order_by, limit, offset, squeeze parameters. This allows gradual migration from 0.14 without requiring immediate rewrites of 100+ fetch() calls per pipeline. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 8c85a9b commit 02bbba6

File tree

1 file changed

+76
-19
lines changed

1 file changed

+76
-19
lines changed

src/datajoint/expression.py

Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -580,29 +580,86 @@ def aggr(self, group, *attributes, exclude_nonmatching=False, **named_attributes
580580
aggregate = aggr # alias for aggr
581581

582582
# ---------- Fetch operators --------------------
583-
@property
584-
def fetch(self):
583+
def fetch(
584+
self,
585+
*attrs,
586+
offset=None,
587+
limit=None,
588+
order_by=None,
589+
format=None,
590+
as_dict=None,
591+
squeeze=False,
592+
download_path=".",
593+
):
594+
"""
595+
Fetch data from the table (backward-compatible with DataJoint 0.14).
596+
597+
.. deprecated:: 2.0
598+
Use the new explicit output methods instead:
599+
- ``to_dicts()`` for list of dictionaries
600+
- ``to_pandas()`` for pandas DataFrame
601+
- ``to_arrays()`` for numpy structured array
602+
- ``to_arrays('a', 'b')`` for tuple of arrays
603+
- ``keys()`` for primary keys
604+
605+
Parameters
606+
----------
607+
*attrs : str
608+
Attributes to fetch. If empty, fetches all.
609+
offset : int, optional
610+
Number of tuples to skip.
611+
limit : int, optional
612+
Maximum number of tuples to return.
613+
order_by : str or list, optional
614+
Attribute(s) for ordering results.
615+
format : str, optional
616+
Output format: 'array' or 'frame' (pandas DataFrame).
617+
as_dict : bool, optional
618+
Return as list of dicts instead of structured array.
619+
squeeze : bool, optional
620+
Remove extra dimensions from arrays. Default False.
621+
download_path : str, optional
622+
Directory for downloaded attachments. Default '.'.
623+
624+
Returns
625+
-------
626+
np.recarray, list[dict], or pd.DataFrame
627+
Query results in requested format.
585628
"""
586-
The fetch() method has been removed in DataJoint 2.0.
629+
import warnings
587630

588-
Use the new explicit output methods instead:
589-
- table.to_dicts() # list of dictionaries
590-
- table.to_pandas() # pandas DataFrame
591-
- table.to_arrays() # numpy structured array
592-
- table.to_arrays('a', 'b') # tuple of numpy arrays
593-
- table.keys() # primary keys as list[dict]
594-
- table.to_polars() # polars DataFrame (requires pip install datajoint[polars])
595-
- table.to_arrow() # PyArrow Table (requires pip install datajoint[arrow])
631+
warnings.warn(
632+
"fetch() is deprecated in DataJoint 2.0. "
633+
"Use to_dicts(), to_pandas(), to_arrays(), or keys() instead.",
634+
DeprecationWarning,
635+
stacklevel=2,
636+
)
596637

597-
For single-row fetch, use fetch1() which is unchanged.
638+
# Apply ordering/limit/offset
639+
expr = self._apply_top(order_by=order_by, limit=limit, offset=offset)
598640

599-
See migration guide: https://docs.datajoint.com/how-to/migrate-from-0x/
600-
"""
601-
raise AttributeError(
602-
"fetch() has been removed in DataJoint 2.0. "
603-
"Use to_dicts(), to_pandas(), to_arrays(), or keys() instead. "
604-
"See table.fetch.__doc__ for details."
605-
)
641+
# Handle format='frame' -> to_pandas()
642+
if format == "frame":
643+
if attrs or as_dict is not None:
644+
raise DataJointError("format='frame' cannot be combined with attrs or as_dict")
645+
return expr.to_pandas(squeeze=squeeze)
646+
647+
# Handle specific attributes requested
648+
if attrs:
649+
if as_dict or as_dict is None:
650+
# fetch('col1', 'col2', as_dict=True) or fetch('col1', 'col2')
651+
# -> proj(...).to_dicts()
652+
return expr.proj(*attrs).to_dicts(squeeze=squeeze)
653+
else:
654+
# fetch('col1', 'col2', as_dict=False) -> tuple of arrays
655+
return expr.to_arrays(*attrs, squeeze=squeeze)
656+
657+
# Handle as_dict=True -> to_dicts()
658+
if as_dict:
659+
return expr.to_dicts(squeeze=squeeze)
660+
661+
# Default: return structured array (legacy behavior)
662+
return expr.to_arrays(squeeze=squeeze)
606663

607664
def fetch1(self, *attrs, squeeze=False):
608665
"""

0 commit comments

Comments
 (0)