Fix registry geo_model to levels mapping

This commit is contained in:
phil 2023-12-26 17:20:36 +05:30
parent 741050db89
commit 6c5acd5a4d
4 changed files with 30 additions and 34 deletions

View file

@ -13,6 +13,7 @@ from gisaf.models.authentication import (
Role, RoleRead, Role, RoleRead,
) )
from gisaf.models.category import Category, CategoryRead from gisaf.models.category import Category, CategoryRead
from gisaf.models.to_migrate import DataProvider
from gisaf.config import conf from gisaf.config import conf
from gisaf.models.bootstrap import BootstrapData from gisaf.models.bootstrap import BootstrapData
from gisaf.models.store import Store from gisaf.models.store import Store
@ -58,13 +59,16 @@ async def login_for_access_token(
return Token(access_token=access_token, token_type='bearer') return Token(access_token=access_token, token_type='bearer')
@api.get("/list") @api.get("/list")
async def list_data_providers(): async def list_data_providers() -> list[DataProvider]:
""" """
Return a list of data providers, for use with the api (graphs, etc) Return a list of data providers, for use with the api (graphs, etc)
:return: :return:
""" """
return [{'name': m.__name__, 'store': m.get_store_name()} return [
for m in registry.values_for_model] DataProvider(
name=model.get_store_name(),
values=[value.get_store_name() for value in values]
) for model, values in registry.values_for_model.items()]
@api.get("/users") @api.get("/users")

View file

@ -16,3 +16,7 @@ class ModelAction(BaseModel):
name: str name: str
icon: str icon: str
formFields: list[FormField] formFields: list[FormField]
class DataProvider(BaseModel):
name: str
values: list[str]

View file

@ -120,9 +120,12 @@ class DownloadPlugin:
class DownloadCSVPlugin(DownloadPlugin): class DownloadCSVPlugin(DownloadPlugin):
async def execute(self, model, item, request): async def execute(self, model, item, request):
from gisaf.registry import registry from gisaf.registry import registry
values_model = registry.values_for_model.get(model) values_models = registry.values_for_model.get(model)
df = await values_model.get_as_dataframe(model_id=item.id) for value_model in values_models:
csv = df.to_csv(date_format='%d/%m/%Y %H:%M', float_format=values_model.float_format) df = await values_models.get_as_dataframe(model_id=item.id)
csv = df.to_csv(date_format='%d/%m/%Y %H:%M', float_format=value_model.float_format)
## TODO: implement multiple values for a model (search for values_for_model)
break
return { return {
'file_name': '{:s}.csv'.format(item.caption), 'file_name': '{:s}.csv'.format(item.caption),
'content_type': 'text/csv', 'content_type': 'text/csv',

View file

@ -6,13 +6,13 @@ import importlib
import pkgutil import pkgutil
from collections import defaultdict from collections import defaultdict
from importlib.metadata import entry_points from importlib.metadata import entry_points
from typing import Any, ClassVar from typing import Any, ClassVar, Literal
from pydantic import create_model from pydantic import create_model
from pydantic_core import PydanticUndefined from pydantic_core import PydanticUndefined
from sqlalchemy import text from sqlalchemy import text
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlmodel import SQLModel, select from sqlmodel import SQLModel, select, inspect
import pandas as pd import pandas as pd
from gisaf.config import conf from gisaf.config import conf
@ -83,6 +83,8 @@ class ModelRegistry:
misc: dict[str, SQLModel] misc: dict[str, SQLModel]
raw_survey_models: dict[str, RawSurveyBaseModel] raw_survey_models: dict[str, RawSurveyBaseModel]
survey_models: dict[str, SurveyModel] survey_models: dict[str, SurveyModel]
## TODO: implement multiple values for a model (search for values_for_model)
values_for_model: dict[GeoModel, list[PlottableModel]]
def __init__(self) -> None: def __init__(self) -> None:
""" """
@ -261,17 +263,13 @@ class ModelRegistry:
''' '''
Build a dict for quick access to the values from a model Build a dict for quick access to the values from a model
''' '''
logger.warning(ToMigrate('populate_values_for_model'))
return
self.values_for_model = {} self.values_for_model = {}
for model_value in self.values.values(): for model_value in self.values.values():
for field in model_value.model_fields.values(): for relationship in inspect(model_value).relationships:
foreign_key = getattr(field, 'foreign_key', False) model = self.stores.loc[relationship.target.fullname, 'model']
if foreign_key and foreign_key is not PydanticUndefined: if model not in self.values_for_model:
breakpoint() self.values_for_model[model] = []
model = ... self.values_for_model[model].append(model_value)
self.values_for_model[model] = model_value
def scan_entry_points(self, name): def scan_entry_points(self, name):
""" """
@ -286,15 +284,15 @@ class ModelRegistry:
logger.warning(err) logger.warning(err)
return named_objects return named_objects
def add_model(self, model) -> str: def add_model(self, model) -> Literal['GeoModel', 'PlottableModel', 'Other model']:
""" """
Add the model Add the model to its proper dict for reference, return the type
:return: Model type (one of {'GeoModel', 'PlottableModel', 'Other model'})
""" """
# if not hasattr(model, 'get_store_name'): # if not hasattr(model, 'get_store_name'):
# raise NotInRegistry() # raise NotInRegistry()
table_name = model.get_store_name() table_name = model.get_store_name()
if issubclass(model, GeoModel) and not issubclass(model, RawSurveyBaseModel) and not model.hidden: if issubclass(model, GeoModel) and not \
issubclass(model, RawSurveyBaseModel) and not model.hidden:
self.geom_custom[table_name] = model self.geom_custom[table_name] = model
return 'GeoModel' return 'GeoModel'
elif issubclass(model, PlottableModel): elif issubclass(model, PlottableModel):
@ -358,19 +356,6 @@ class ModelRegistry:
resp['externalRecordUrl'] = item.get_external_record_url() resp['externalRecordUrl'] = item.get_external_record_url()
return resp return resp
def get_other_model_from_table_name(self, table_name):
"""
Utility func to get a non-geom model from a table name
:param table_name: str
:return: model or None
"""
for model in registry.other.values():
if model.__tablename__ == table_name:
return model
for model in registry.values.values():
if model.__tablename__ == table_name:
return model
async def make_stores(self): async def make_stores(self):
""" """
Make registry for primary groups, categories and survey stores using Pandas dataframes. Make registry for primary groups, categories and survey stores using Pandas dataframes.