voxel51 / fiftyone

Refine high-quality datasets and visual AI models
https://fiftyone.ai
Apache License 2.0
8.86k stars 560 forks source link

[BUG] The fields "{'db_field'}" do not exist on the document "SampleFieldDocument" #1094

Closed luke-iqt closed 3 years ago

luke-iqt commented 3 years ago

System information

Describe the problem

I have just began encountering the following error when I try to load a Voxel51 dataset. The dataset had been migrated to a newer version of Voxel a while ago, but had worked fine after that migration. This problem started after the instance had been restarted. Is it possible the underlying MongoDB has been corrupted?

Code to reproduce issue

import fiftyone as fo
dataset_name = "jsm-test-dataset" # Name of the Voxel51 Dataset to use
dataset = fo.load_dataset(dataset_name) 

Log:

---------------------------------------------------------------------------
FieldDoesNotExist                         Traceback (most recent call last)
<ipython-input-2-bce0580c7d7e> in <module>
      3 import os
      4 
----> 5 dataset = fo.load_dataset(dataset_name)

/usr/local/lib/python3.6/dist-packages/fiftyone/core/dataset.py in load_dataset(name)
     97         ValueError: if no dataset exists with the given name
     98     """
---> 99     return Dataset(name, _create=False)
    100 
    101 

/usr/local/lib/python3.6/dist-packages/fiftyone/core/singletons.py in __call__(cls, name, _create, *args, **kwargs)
     31         ):
     32             instance = cls.__new__(cls)
---> 33             instance.__init__(name=name, _create=_create, *args, **kwargs)
     34             name = instance.name  # `__init__` may have changed `name`
     35             cls._instances[name] = instance

/usr/local/lib/python3.6/dist-packages/fiftyone/core/dataset.py in __init__(self, name, persistent, overwrite, _create, _migrate, _patches)
    239                 self._sample_doc_cls,
    240                 self._frame_doc_cls,
--> 241             ) = _load_dataset(name, migrate=_migrate)
    242 
    243         self._evaluation_cache = {}

/usr/local/lib/python3.6/dist-packages/fiftyone/core/dataset.py in _load_dataset(name, migrate)
   3465     try:
   3466         # pylint: disable=no-member
-> 3467         dataset_doc = foo.DatasetDocument.objects.get(name=name)
   3468     except moe.DoesNotExist:
   3469         raise ValueError("Dataset '%s' not found" % name)

/usr/local/lib/python3.6/dist-packages/mongoengine/queryset/base.py in get(self, *q_objs, **query)
    258 
    259         try:
--> 260             result = next(queryset)
    261         except StopIteration:
    262             msg = "%s matching query does not exist." % queryset._document._class_name

/usr/local/lib/python3.6/dist-packages/mongoengine/queryset/base.py in __next__(self)
   1596             raw_doc,
   1597             _auto_dereference=self._auto_dereference,
-> 1598             only_fields=self.only_fields,
   1599         )
   1600 

/usr/local/lib/python3.6/dist-packages/mongoengine/base/document.py in _from_son(cls, son, _auto_dereference, only_fields, created)
    761                 try:
    762                     data[field_name] = (
--> 763                         value if value is None else field.to_python(value)
    764                     )
    765                     if field_name != field.db_field:

/usr/local/lib/python3.6/dist-packages/mongoengine/base/fields.py in to_python(self, value)
    357             self.field._auto_dereference = self._auto_dereference
    358             value_dict = {
--> 359                 key: self.field.to_python(item) for key, item in value.items()
    360             }
    361         else:

/usr/local/lib/python3.6/dist-packages/mongoengine/base/fields.py in <dictcomp>(.0)
    357             self.field._auto_dereference = self._auto_dereference
    358             value_dict = {
--> 359                 key: self.field.to_python(item) for key, item in value.items()
    360             }
    361         else:

/usr/local/lib/python3.6/dist-packages/mongoengine/fields.py in to_python(self, value)
    744         if not isinstance(value, self.document_type):
    745             return self.document_type._from_son(
--> 746                 value, _auto_dereference=self._auto_dereference
    747             )
    748         return value

/usr/local/lib/python3.6/dist-packages/mongoengine/base/document.py in _from_son(cls, son, _auto_dereference, only_fields, created)
    782 
    783         obj = cls(
--> 784             __auto_convert=False, _created=created, __only_fields=only_fields, **data
    785         )
    786         obj._changed_fields = []

/usr/local/lib/python3.6/dist-packages/fiftyone/core/odm/document.py in __init__(self, *args, **kwargs)
    539 
    540     def __init__(self, *args, **kwargs):
--> 541         super().__init__(*args, **kwargs)
    542         self.validate()
    543 

/usr/local/lib/python3.6/dist-packages/mongoengine/document.py in __init__(self, *args, **kwargs)
     80 
     81     def __init__(self, *args, **kwargs):
---> 82         super().__init__(*args, **kwargs)
     83         self._instance = None
     84         self._changed_fields = []

/usr/local/lib/python3.6/dist-packages/mongoengine/base/document.py in __init__(self, *args, **values)
     97                     _undefined_fields, self._class_name
     98                 )
---> 99                 raise FieldDoesNotExist(msg)
    100 
    101         if self.STRICT and not self._dynamic:

FieldDoesNotExist: The fields "{'db_field'}" do not exist on the document "SampleFieldDocument"
fiftyone migrate --info

FiftyOne package version: 0.9.3
Database version: 0.9.3

dataset           version
----------------  ---------
jsm-test-dataset  0.9.3
plane-dataset     0.9.3

It is able to successfully load the other dataset plane-dataset, so I think the overall install is working. Is there some sort of repair command that can be run?

What areas of FiftyOne does this bug affect?

Willingness to contribute

The FiftyOne Community encourages bug fix contributions. Would you or another member of your organization be willing to contribute a fix for this bug to the FiftyOne codebase?

benjaminpkane commented 3 years ago

Hi @luke-iqt. It looks like you've run into a version downgrade issue.

I'd recommend upgrading fiftyone.

pip install -U fiftyone

You'll have to upgrade, even if you wish to use 0.9.3. Once you have upgraded, you can upgrade your datasets with:

fiftyone migrate --all --version 0.11.1

You should be all set at this point. But if you want to use 0.9.3, then you can downgrade in the following way:

fiftyone migrate --all --version 0.9.3
pip install fiftyone==0.9.3

See here for more formal information about downgrading fiftyone. At high level, fiftyone automatically handles upgrades for you, but downgrades must be done manually.

luke-iqt commented 3 years ago

You nailed it!!!! Thanks so much! I had upgraded Voxel51 to get some of the newer features... but everything is running inside a container and I forgot to rebuild the Docker Image also. When I rebooted, it went back to the older version of Voxel51 that is part of the container image.

FiftyOne package version: 0.11.1
Database version: 0.11.1

dataset           version
----------------  ---------
jsm-test-dataset  0.11.1
plane-dataset     0.9.3
luke-iqt commented 3 years ago

I think one thing that confused me was when I did fiftyone migrate --info when I had the downgrade issue, it reported that the dataset version matched the current version. Shouldn't it have list 0.11.1 instead of 0.9.3?

Checking the dataset versions could be a good way to spot a downgrade problem.

benjaminpkane commented 3 years ago

Yes, you make a good point, it should have. I think there is an improvement we can make on our end.

The details of it are, right now, downgrades automatically happen. Even when the older (current) version doesn't have access to the full revision history. TLDR; stay tuned!