Repository: voxel51/fiftyone

Issue:
[BUG] App can't be opened when deployment contains datasets with no creation date
After upgrading to `fiftyone==0.16.1`, I get the error below when trying to launch the App.

Note that this is a serious issue because it prevents me from loading the App at all, including directly loading a new dataset:

```py
import fiftyone as fo

session = fo.launch_app()  # fails

dataset = fo.Dataset()
session = fo.launch_app(dataset)  # also fails
```

```
missing value for field "created_at"
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/graphql/execution/execute.py", line 353, in await_result
return await result # type: ignore
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/graphql/execution/execute.py", line 456, in get_results
await gather(*(results[field] for field in awaitable_fields)),
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/graphql/execution/execute.py", line 632, in await_result
self.handle_field_error(error, return_type)
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/graphql/execution/execute.py", line 666, in handle_field_error
raise error
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/graphql/execution/execute.py", line 625, in await_result
return_type, field_nodes, info, path, await result
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/strawberry/extensions/directives.py", line 19, in resolve
result = await await_maybe(_next(root, info, *args, **kwargs))
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/strawberry/utils/await_maybe.py", line 12, in await_maybe
return await value
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/strawberry/schema/schema_converter.py", line 396, in _async_resolver
return await await_maybe(_get_result(_source, strawberry_info, **kwargs))
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/strawberry/utils/await_maybe.py", line 12, in await_maybe
return await value
File "/Users/Brian/dev/fiftyone/fiftyone/server/paginator.py", line 110, in paginate
return await get_items(
File "/Users/Brian/dev/fiftyone/fiftyone/server/paginator.py", line 75, in get_items
edges.append(Edge(node=from_db(doc), cursor=str(_id)))
File "/Users/Brian/dev/fiftyone/fiftyone/server/paginator.py", line 108, in from_db
return from_dict(cls, doc, config=Config(check_types=False))
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/dacite/core.py", line 75, in from_dict
raise MissingValueError(field.name)
```

The reason is that I have some old datasets that were created prior to the introduction of the `DatasetDocument.created_at` field, and the App doesn't like that the `created_at` field is missing from those datasets.

Looks like `created_at` was added in [v0.14.0](https://github.com/voxel51/fiftyone/blob/3771c6f3aeb1d391c8fce9b73b592061c65a3903/fiftyone/migrations/revisions/v0_14_0.py#L14). In my case, all pre-v0.14.0 datasets had been upgraded to v0.15.1, but, for some reason, `created_at` was missing from their `DatasetDocument` rather than being set to `None`.

Not sure why `created_at` was missing in my particular case, but, in general, since datasets are only lazily migrated when they are loaded, the App needs to take extra care not to raise any fatal error when non-migrated datasets are involved. Or we must abandon lazy migration altogether.


Discussion:
On `fiftyone==0.16.2`, I now get:

```
missing value for field "brain_methods.version"
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/graphql/execution/execute.py", line 353, in await_result
return await result # type: ignore
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/graphql/execution/execute.py", line 456, in get_results
await gather(*(results[field] for field in awaitable_fields)),
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/graphql/execution/execute.py", line 632, in await_result
self.handle_field_error(error, return_type)
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/graphql/execution/execute.py", line 666, in handle_field_error
raise error
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/graphql/execution/execute.py", line 625, in await_result
return_type, field_nodes, info, path, await result
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/strawberry/extensions/directives.py", line 19, in resolve
result = await await_maybe(_next(root, info, *args, **kwargs))
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/strawberry/utils/await_maybe.py", line 12, in await_maybe
return await value
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/strawberry/schema/schema_converter.py", line 396, in _async_resolver
return await await_maybe(_get_result(_source, strawberry_info, **kwargs))
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/strawberry/utils/await_maybe.py", line 12, in await_maybe
return await value
File "/Users/Brian/dev/fiftyone/fiftyone/server/paginator.py", line 110, in paginate
return await get_items(
File "/Users/Brian/dev/fiftyone/fiftyone/server/paginator.py", line 75, in get_items
edges.append(Edge(node=from_db(doc), cursor=str(_id)))
File "/Users/Brian/dev/fiftyone/fiftyone/server/paginator.py", line 108, in from_db
return from_dict(cls, doc, config=Config(check_types=False))
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/dacite/core.py", line 63, in from_dict
value = _build_value(type_=field.type, data=transformed_value, config=config)
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/dacite/core.py", line 90, in _build_value
return _build_value_for_collection(collection=type_, data=data, config=config)
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/dacite/core.py", line 140, in _build_value_for_collection
return data_type(_build_value(type_=item_type, data=item, config=config) for item in data)
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/dacite/core.py", line 140, in <genexpr>
return data_type(_build_value(type_=item_type, data=item, config=config) for item in data)
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/dacite/core.py", line 92, in _build_value
return from_dict(data_class=type_, data=data, config=config)
File "/Users/Brian/dev/env/fo/lib/python3.9/site-packages/dacite/core.py", line 75, in from_dict
raise MissingValueError(field.name)
```


Resolving patch:
diff --git a/fiftyone/server/query.py b/fiftyone/server/query.py
--- a/fiftyone/server/query.py
+++ b/fiftyone/server/query.py
@@ -75,34 +75,34 @@ class RunConfig:
 @gql.interface
 class Run:
     key: str
-    version: str
-    timestamp: datetime
-    config: RunConfig
-    view_stages: t.List[str]
+    version: t.Optional[str]
+    timestamp: t.Optional[datetime]
+    config: t.Optional[RunConfig]
+    view_stages: t.Optional[t.List[str]]
 
 
 @gql.type
 class BrainRunConfig(RunConfig):
     embeddings_field: t.Optional[str]
-    method: str
+    method: t.Optional[str]
     patches_field: t.Optional[str]
 
 
 @gql.type
 class BrainRun(Run):
-    config: BrainRunConfig
+    config: t.Optional[BrainRunConfig]
 
 
 @gql.type
 class EvaluationRunConfig(RunConfig):
-    gt_field: str
-    pred_field: str
-    method: str
+    gt_field: t.Optional[str]
+    pred_field: t.Optional[str]
+    method: t.Optional[str]
 
 
 @gql.type
 class EvaluationRun(Run):
-    config: EvaluationRunConfig
+    config: t.Optional[EvaluationRunConfig]
 
 
 @gql.type


Test patch: