Skip to content

Commit 5a9bc4a

Browse files
merge: Integrate modern-fetch-api branch
Merged claude/modern-fetch-api with include_key support for to_arrays(). Resolved docstring conflict by keeping NumPy style with new functionality. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
2 parents 13b73a0 + f081477 commit 5a9bc4a

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

src/datajoint/expression.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,12 +908,14 @@ def to_arrays(
908908
If no attrs: structured array (recarray) of all columns.
909909
If single attr: 1D array of values.
910910
If multiple attrs: tuple of arrays.
911+
With include_key=True: (keys, *arrays) where keys is list[dict].
911912
912913
Examples
913914
--------
914915
>>> table.to_arrays() # Structured array of all columns
915916
>>> table.to_arrays('x', 'y') # Tuple of two arrays
916917
>>> x = table.to_arrays('x') # Single array
918+
>>> keys, a, b = table.to_arrays('a', 'b', include_key=True) # With keys
917919
"""
918920
from functools import partial
919921

@@ -931,6 +933,10 @@ def to_arrays(
931933
projected = expr.proj(*fetch_attrs)
932934
dicts = projected.to_dicts(squeeze=squeeze, download_path=download_path)
933935

936+
# Extract keys if requested
937+
if include_key:
938+
keys = [{k: d[k] for k in expr.primary_key} for d in dicts]
939+
934940
# Extract arrays for requested attributes
935941
result_arrays = []
936942
for attr in attrs:
@@ -943,6 +949,8 @@ def to_arrays(
943949
arr = np.array(values, dtype=object)
944950
result_arrays.append(arr)
945951

952+
if include_key:
953+
return (keys, *result_arrays)
946954
return result_arrays[0] if len(attrs) == 1 else tuple(result_arrays)
947955
else:
948956
# Fetch all columns as structured array

src/datajoint/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# version bump auto managed by Github Actions:
22
# label_prs.yaml(prep), release.yaml(bump), post_release.yaml(edit)
33
# manually set this version will be eventually overwritten by the above actions
4-
__version__ = "2.0.0a12"
4+
__version__ = "2.0.0a13"

tests/integration/test_fetch.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,56 @@ def test_lazy_iteration(lang, languages):
344344
first = next(iter_obj)
345345
assert isinstance(first, dict)
346346
assert "name" in first and "language" in first
347+
348+
349+
def test_to_arrays_include_key(lang, languages):
350+
"""Test to_arrays with include_key=True returns keys as list of dicts"""
351+
# Fetch with include_key=True
352+
keys, names, langs = lang.to_arrays("name", "language", include_key=True, order_by="KEY")
353+
354+
# keys should be a list of dicts with primary key columns
355+
assert isinstance(keys, list)
356+
assert all(isinstance(k, dict) for k in keys)
357+
assert all(set(k.keys()) == {"name", "language"} for k in keys)
358+
359+
# names and langs should be numpy arrays
360+
assert isinstance(names, np.ndarray)
361+
assert isinstance(langs, np.ndarray)
362+
363+
# Length should match
364+
assert len(keys) == len(names) == len(langs) == len(languages)
365+
366+
# Keys should match the data
367+
for key, name, language in zip(keys, names, langs):
368+
assert key["name"] == name
369+
assert key["language"] == language
370+
371+
# Keys should be usable for restrictions
372+
first_key = keys[0]
373+
restricted = lang & first_key
374+
assert len(restricted) == 1
375+
assert restricted.fetch1("name") == first_key["name"]
376+
377+
378+
def test_to_arrays_include_key_single_attr(subject):
379+
"""Test to_arrays include_key with single attribute"""
380+
keys, species = subject.to_arrays("species", include_key=True)
381+
382+
assert isinstance(keys, list)
383+
assert isinstance(species, np.ndarray)
384+
assert len(keys) == len(species)
385+
386+
# Verify keys have only primary key columns
387+
assert all("subject_id" in k for k in keys)
388+
389+
390+
def test_to_arrays_without_include_key(lang):
391+
"""Test that to_arrays without include_key doesn't return keys"""
392+
result = lang.to_arrays("name", "language")
393+
394+
# Should return tuple of arrays, not (keys, ...)
395+
assert isinstance(result, tuple)
396+
assert len(result) == 2
397+
names, langs = result
398+
assert isinstance(names, np.ndarray)
399+
assert isinstance(langs, np.ndarray)

0 commit comments

Comments
 (0)