diff --git a/src/models.py b/src/models.py index cd6d36f..e372e16 100644 --- a/src/models.py +++ b/src/models.py @@ -108,15 +108,46 @@ class Rooms(Base): address = relationship("Addresses", back_populates="rooms") +class StatusTypes(Base): + __tablename__ = "status_types" + + status_id = Column(Integer, primary_key=True) + name = Column(String, nullable=False) + full_name = Column(String, nullable=False) + + name_en = Column(String, nullable=False) + full_name_en = Column(String, nullable=False) + + updated_at = Column(Date, nullable=False) + + +class PurposeTypes(Base): + __tablename__ = "purpose_types" + + purpose_id = Column(Integer, primary_key=True) + purpose_group = Column(Integer) + + name = Column(String, nullable=False) + full_name = Column(String, nullable=False) + + name_en = Column(String, nullable=False) + full_name_en = Column(String, nullable=False) + + updated_at = Column(Date, nullable=False) + + parcels = relationship("Parcels", back_populates="purpose") + + class Parcels(Base): __tablename__ = "parcels" ogc_fid = Column(Integer, primary_key=True) unique_number = Column(Integer, nullable=False, index=True) cadastral_number = Column(String, nullable=False, index=True) - + status_id = Column(Integer, nullable=True) - purpose_id = Column(Integer, nullable=False) + purpose_id = Column(Integer, ForeignKey("purpose_types.purpose_id"), nullable=False) + purpose = relationship("PurposeTypes", back_populates="parcels") updated_at = Column(Date, nullable=False) area_ha = Column(Double, nullable=False) @@ -127,4 +158,3 @@ class Parcels(Base): geom = Column( Geometry(srid=3346, nullable=False), nullable=False ) - diff --git a/src/schemas.py b/src/schemas.py index 5f7429c..36dfa82 100644 --- a/src/schemas.py +++ b/src/schemas.py @@ -180,19 +180,25 @@ class Room(BaseModel): address: ShortAddress = Field(description="Address of the room") -class ShortParcel(BaseModel): +class Purpose(BaseModel): + purpose_id: int = Field(description="Purpose ID") + purpose_group: int = Field(description="Purpose group") + name: str = Field(description="Purpose name") + full_name: str = Field(description="Purpose full name") + full_name_en: str = Field(description="Purpose full name in english") + + +class Parcel(BaseModel): unique_number: int = Field(description="Unique number of the parcel") cadastral_number: str = Field(description="Cadastral number of the parcel") updated_at: datetime.date = Field(description="Date of update of the parcel") - purpose_id: int = Field(description="Purpose ID of the parcel") status_id: Optional[int] = Field(description="Status ID of the parcel") area_ha: float = Field(description="Area of the parcel in hectares") + geometry: Geometry = Field(description="Polygon geometry of the parcel") + purpose: Purpose = Field(description="Purpose of the parcel") municipality: ShortMunicipality = Field(description="Municipality information the parcel belongs to") -class Parcel(ShortParcel): - geometry: Geometry = Field(description="Polygon geometry of the parcel") - class HealthCheck(BaseModel): """Response model to validate and return when performing a health check.""" diff --git a/src/services.py b/src/services.py index 31995b9..21d9493 100644 --- a/src/services.py +++ b/src/services.py @@ -64,6 +64,15 @@ type_=JSONB, ).label("address") +_purpose_type_object = func.json_object( + text("'purpose_id', purpose_types.purpose_id"), + text("'purpose_group', purpose_types.purpose_group"), + text("'name', purpose_types.name"), + text("'full_name', purpose_types.full_name"), + text("'full_name_en', purpose_types.full_name_en"), + type_=JSONB, +).label("purpose") + class BaseBoundariesService(abc.ABC): model_class: Type[models.BaseBoundaries] @@ -332,6 +341,7 @@ def _get_select_query( def _filter_by_code(self, query: Select, code: int) -> Select: return query.filter(models.Rooms.code == code) + class ParcelsService(BaseBoundariesService): model_class = models.Parcels @@ -345,17 +355,17 @@ def _get_select_query( models.Parcels.cadastral_number, models.Parcels.area_ha, models.Parcels.updated_at, - models.Parcels.purpose_id, models.Parcels.status_id, _municipality_object, + _purpose_type_object, self._get_geometry_field(models.Parcels.geom, srid, geometry_output_format) ] - return select(*columns).select_from(models.Parcels)\ + return select(*columns).select_from(models.Parcels) \ .outerjoin(models.Parcels.municipality) \ + .outerjoin(models.Parcels.purpose) \ .outerjoin(models.Municipalities.county) - + # Currently not implemented - unique numbers are duplicates def _filter_by_code(self, query: Select, code: int) -> Select: return query -