Remove custom sqlalchemy metadata, manage with __table_args__
Allow sqlmodel queries, with relations Remode join_with mechanisms coming from gino Handlew ith_only_columns in get_df and get_gdf Implement feature-info
This commit is contained in:
parent
1e3678fb69
commit
ec71b6ed15
18 changed files with 353 additions and 141 deletions
|
@ -4,6 +4,7 @@ from datetime import date, datetime
|
|||
from collections import OrderedDict
|
||||
from io import BytesIO
|
||||
from zipfile import ZipFile
|
||||
from functools import cached_property
|
||||
import locale
|
||||
import logging
|
||||
|
||||
|
@ -12,19 +13,16 @@ import geopandas as gpd # type: ignore
|
|||
import shapely # type: ignore
|
||||
import pyproj
|
||||
|
||||
from sqlmodel import SQLModel, Field, Relationship
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
from pydantic import BaseModel
|
||||
|
||||
from geoalchemy2.shape import from_shape
|
||||
from sqlalchemy.dialects.postgresql import BIGINT
|
||||
from sqlalchemy import BigInteger, Column, MetaData, String, func, and_, text
|
||||
from sqlmodel import select, Field, Relationship
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
from sqlalchemy import BigInteger, MetaData, String, func, and_, text
|
||||
from sqlalchemy.sql import sqltypes
|
||||
from sqlalchemy.orm import declared_attr
|
||||
from psycopg2.extensions import adapt
|
||||
|
||||
from geoalchemy2.shape import from_shape
|
||||
from geoalchemy2.types import Geometry, WKBElement
|
||||
|
||||
from shapely import wkb
|
||||
from shapely import wkb, from_wkb
|
||||
from shapely.geometry import mapping
|
||||
from shapely.ops import transform # type: ignore
|
||||
|
||||
|
@ -35,15 +33,15 @@ from shapefile import (
|
|||
POLYGON, POLYGONZ,
|
||||
)
|
||||
|
||||
|
||||
from gisaf.database import db_session
|
||||
from gisaf.config import conf
|
||||
from gisaf.models.models_base import Model
|
||||
from gisaf.models.metadata import survey, raw_survey
|
||||
from gisaf.models.survey import Equipment, Surveyor, Accuracy
|
||||
from gisaf.models.metadata import (
|
||||
gisaf_survey_table_args, gisaf_admin_table_args, survey_table_args)
|
||||
from gisaf.models.misc import Qml
|
||||
from gisaf.models.category import Category
|
||||
from gisaf.models.project import Project
|
||||
# from gisaf.models.survey import Equipment, Surveyor, Accuracy
|
||||
# from gisaf.models.project import Project
|
||||
|
||||
LOCALE_DATE_FORMAT = locale.nl_langinfo(locale.D_FMT)
|
||||
|
||||
|
@ -82,14 +80,14 @@ class BaseSurveyModel(BaseModel):
|
|||
- projected ('V_*')
|
||||
"""
|
||||
id: int | None = Field(sa_type=BigInteger, primary_key=True, default=None)
|
||||
equip_id: int = Field(foreign_key='equipment.id')
|
||||
# equipment: Equipment = Relationship()
|
||||
srvyr_id: int = Field('surveyor.id')
|
||||
# surveyor: Surveyor = Relationship()
|
||||
accur_id: int = Field('accuracy.id')
|
||||
# accuracy: Accuracy = Relationship()
|
||||
project_id: int = Field('project.id')
|
||||
# project: Project = Relationship()
|
||||
equip_id: int = Field(
|
||||
foreign_key=gisaf_survey_table_args['schema'] + '.equipment.id')
|
||||
srvyr_id: int = Field(
|
||||
foreign_key=gisaf_survey_table_args['schema'] + '.surveyor.id')
|
||||
accur_id: int = Field(
|
||||
foreign_key=gisaf_survey_table_args['schema'] + '.accuracy.id')
|
||||
project_id: int = Field(
|
||||
foreign_key=gisaf_admin_table_args['schema'] + '.project.id')
|
||||
|
||||
orig_id: str
|
||||
date: date
|
||||
|
@ -151,7 +149,7 @@ class SurveyModel(BaseSurveyModel):
|
|||
"""
|
||||
Base mixin class for defining final (reprojected) survey data, with a status
|
||||
"""
|
||||
metadata: ClassVar[MetaData] = survey
|
||||
__table_args__ = survey_table_args
|
||||
# status: str = Field(sa_type=String(1))
|
||||
|
||||
get_gdf_with_related: ClassVar[bool] = False
|
||||
|
@ -182,6 +180,10 @@ class SurveyModel(BaseSurveyModel):
|
|||
'gisaf_admin_project_skip_columns',
|
||||
]
|
||||
|
||||
@declared_attr
|
||||
def __tablename__(cls) -> str:
|
||||
return cls.__name__ # type: nocheck
|
||||
|
||||
async def get_survey_info(self):
|
||||
info = await super(SurveyModel, self).get_survey_info()
|
||||
if self.srvyr_id:
|
||||
|
@ -203,7 +205,7 @@ class SurveyModel(BaseSurveyModel):
|
|||
|
||||
@property
|
||||
def caption(self):
|
||||
return '{self.category.description} [{self.category.group}-{self.category.minor_group_1}] #{self.id:d}'.format(self=self)
|
||||
return '{self.category.description} - {self.category.name} [{self.category.group}-{self.category.minor_group_1}] #{self.id:d}'.format(self=self)
|
||||
|
||||
@classmethod
|
||||
async def get_popup(cls, df):
|
||||
|
@ -425,30 +427,28 @@ class GeoModelNoStatus(Model):
|
|||
|
||||
async def get_tags(self):
|
||||
from gisaf.models.tags import Tags
|
||||
tags = await Tags.get_df(
|
||||
where=and_(
|
||||
Tags.store == self.__class__.get_store_name(),
|
||||
Tags.ref_id == self.id
|
||||
),
|
||||
with_only_columns=['tags']
|
||||
)
|
||||
if len(tags) > 0:
|
||||
return tags.loc[0, 'tags']
|
||||
else:
|
||||
return {}
|
||||
async with db_session() as session:
|
||||
query = select(Tags.tags).where(Tags.store == self.get_store_name(),
|
||||
Tags.ref_id == self.id)
|
||||
tags = await session.exec(query)
|
||||
return tags.one_or_none() or {}
|
||||
|
||||
@property
|
||||
@cached_property
|
||||
def shapely_geom(self):
|
||||
if not hasattr(self, '_shapely_geom'):
|
||||
if isinstance(self.geom, WKBElement):
|
||||
bytes = self.geom.data
|
||||
if bytes:
|
||||
self._shapely_geom = wkb.loads(bytes)
|
||||
else:
|
||||
self._shapely_geom = None
|
||||
else:
|
||||
self._shapely_geom = None
|
||||
return self._shapely_geom
|
||||
return from_wkb(self.geom.data)
|
||||
|
||||
# @property
|
||||
# def shapely_geom(self):
|
||||
# if not hasattr(self, '_shapely_geom'):
|
||||
# if isinstance(self.geom, WKBElement):
|
||||
# bytes = self.geom.data
|
||||
# if bytes:
|
||||
# self._shapely_geom = wkb.loads(bytes)
|
||||
# else:
|
||||
# self._shapely_geom = None
|
||||
# else:
|
||||
# self._shapely_geom = None
|
||||
# return self._shapely_geom
|
||||
|
||||
def get_bgColor(self):
|
||||
"""
|
||||
|
@ -760,6 +760,7 @@ class GeoModelNoStatus(Model):
|
|||
def get_attachment_base_dir(cls):
|
||||
return Path(conf.attachments.base_dir) / cls.get_attachment_dir()
|
||||
|
||||
|
||||
class GeoModel(GeoModelNoStatus):
|
||||
status: ClassVar[str] = 'E'
|
||||
"""
|
||||
|
@ -1061,7 +1062,7 @@ class RawSurveyBaseModel(BaseSurveyModel, GeoPointModelNoStatus):
|
|||
"""
|
||||
Abstract base class for category based raw survey point models
|
||||
"""
|
||||
metadata: ClassVar[MetaData] = raw_survey
|
||||
# metadata: ClassVar[MetaData] = raw_survey
|
||||
geom: Annotated[str, WKBElement] = Field(sa_type=Geometry('POINTZ', dimension=3,
|
||||
srid=conf.geo.raw_survey.srid))
|
||||
status: str = Field(sa_type=String(1))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue