Skip to content

Commit bd48cc2

Browse files
SudipSinhaclaude
andcommitted
fix(datasource): handle numpy array tags from MariaDB in get_dataframe_by_tag
MariaDB round-trips tags through json/gzip/LONGBLOB, producing numpy arrays instead of Python lists. The isinstance(cell, list) check returned False, causing all rows to be filtered out. Extract tags via _extract_tags helper that handles both list and np.ndarray. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Sudip Sinha <Sudip.Sinha@RedHat.com>
1 parent 5d6d913 commit bd48cc2

2 files changed

Lines changed: 44 additions & 4 deletions

File tree

src/service/data/datasources/data_source.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44
import os
55

6+
import numpy as np
67
import pandas as pd
78

89
from src.service.constants import (
@@ -196,10 +197,14 @@ async def get_dataframe_by_tag(self, model_id: str, tag: str) -> pd.DataFrame:
196197
if tags_col < 0:
197198
return pd.DataFrame()
198199

199-
mask = [
200-
tag in (row[tags_col] if isinstance(row[tags_col], list) else [])
201-
for row in metadata
202-
]
200+
def _extract_tags(cell: object) -> list:
201+
if isinstance(cell, np.ndarray):
202+
return cell.tolist()
203+
if isinstance(cell, list):
204+
return cell
205+
return []
206+
207+
mask = [tag in _extract_tags(row[tags_col]) for row in metadata]
203208
filtered_input = input_data[mask]
204209

205210
df_data: dict[str, object] = {}

tests/service/data/datasources/test_datasource.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,3 +524,38 @@ async def test_returns_empty_when_no_data(
524524
df = await data_source.get_dataframe_by_tag("test-model", "TRAINING")
525525

526526
assert len(df) == 0
527+
528+
@patch("src.service.data.datasources.data_source.ModelData")
529+
@pytest.mark.asyncio
530+
async def test_handles_numpy_array_tags_from_mariadb(
531+
self, mock_model_data_class: Mock, data_source: DataSource
532+
) -> None:
533+
"""Tags stored as numpy arrays (MariaDB round-trip) are handled."""
534+
mock = Mock(spec=ModelData)
535+
mock.column_names = AsyncMock(
536+
return_value=(
537+
np.array(["feature1"]),
538+
np.array(["output"]),
539+
np.array(["id", "iso_time", "unix_timestamp", "tags"]),
540+
),
541+
)
542+
mock.data = AsyncMock(
543+
return_value=(
544+
np.array([[1.0], [2.0], [3.0]]),
545+
np.array([[0.0], [1.0], [0.0]]),
546+
np.array(
547+
[
548+
["id_0", "t0", 0.0, np.array(["TRAINING"])],
549+
["id_1", "t1", 1.0, np.array(["unlabeled"])],
550+
["id_2", "t2", 2.0, np.array(["TRAINING"])],
551+
],
552+
dtype=object,
553+
),
554+
),
555+
)
556+
mock_model_data_class.return_value = mock
557+
558+
df = await data_source.get_dataframe_by_tag("test-model", "TRAINING")
559+
560+
assert len(df) == 2 # noqa: PLR2004
561+
assert df["feature1"].tolist() == [1.0, 3.0]

0 commit comments

Comments
 (0)