Skip to content

find() always returns empty list with Nested Model even though JSONModel is used (Silently) #675

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
autolyticus opened this issue Jan 10, 2025 · 1 comment
Labels
bug Something isn't working good example

Comments

@autolyticus
Copy link

Minimal example:

'''redis_storage.py'''
from redis_om import JsonModel, Field
from typing import Dict, Any, Optional

class ExperimentMetadata(JsonModel):
    class Meta:
        embedded = True

    factors: Dict[str, Any] = Field(default_factory=dict)
    results: Dict[str, Any] = Field(default_factory=dict)
    deployment_metadata: Dict[str, Any] = Field(default_factory=dict)
    dashboard_url: Optional[str] = None
    explore_url: Optional[str] = None

class Experiment(JsonModel):
    exp_name: str = Field(index=True)
    experiment_description: str = Field(default="", index=True)
    experiment_metadata: ExperimentMetadata = Field(default_factory=ExperimentMetadata)

class ExpStorage:
    @staticmethod
    def find_experiments_by_name(name: str) -> list[Experiment]:
        # Migrator().run()
        return Experiment.find(Experiment.exp_name == name).all()
'''test_redis_storage.py'''
import pytest
from os import getenv, environ
from pytest_docker_tools import container

redis = container(
    name="test-redis",
    image="redis/redis-stack:7.2.0-v13",
    ports={6379: 16379, 8001: 18001},
)

environ["REDIS_OM_URL"] = f"redis://localhost:16379/0"
from greenflow.redis_storage import Experiment, ExperimentMetadata, ExpStorage


@pytest.fixture
def storage(redis):
    from redis_om import get_redis_connection
    """Fixture for ExpStorage instance"""
    # Migrator().run()
    redis = get_redis_connection(url=getenv("REDIS_OM_URL"))

    load_gin(exp_name="test-platform", test=True)
    storage = ExpStorage()

    yield storage

    # Cleanup: Delete all keys after each test
    redis.flushdb()
    
class TestExpStorage:
    def test_find_experiments_by_name(self, storage):
        from redis_om import Migrator
        """Test finding experiments by name"""
        # Create multiple experiments
        exp1 = Experiment(exp_name="test1")
        exp1.save()

        exp2 = Experiment(exp_name="test2")
        exp2.save()
        Migrator().run()

        results = Experiment.find(Experiment.exp_name == "test1").all()

        assert len(results) == 1
image When the test runs (and fails), I can see that the redis instance does have correct keys inserted. However, the assertion always fails as an empty list is returned.

I believe this is because ExperimentMetadata is a JsonModel. In fact, I tried changing it to a Dict[str, Any] and it still doesn't work and returns an empty list

@abrookins abrookins added bug Something isn't working good example labels Jan 30, 2025
@pramttl
Copy link

pramttl commented Apr 15, 2025

I also ran into this issue, I started with an empty db, created model instances with .save() and then, ran find().all() which returned nothing, despite the fact that the instance was saved.

I investigated this for quite a bit and ultimately narrowed down the cause to an optional Dict field that looked like this:

class MyModel(JsonModel):
     # Other fields

     this = Optional[Dict[str, int]] = Field(default_factory=dict)
     # this field caused indexing to fail

this field which is of type Optional[Dict[str, int]], caused indexing to fail for the whole object (including the other fields/values). When I called my_model_instance.save(), I expected the instance to be indexed but it was not indexed, but there was no error/warning during model.save() that would make me aware that indexing failed. I only realized the issue after realizing that MyModel.find().all() returned nothing and later checking that indexes were not being populated (using FT.INFO)

Once I removed this field, the automatic-indexing on calling .save() worked and find().all() started working again as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good example
Projects
None yet
Development

No branches or pull requests

3 participants