Skip to content
Snippets Groups Projects
model.py 3.69 KiB
# annotations import is required for sqlalchemy annotations to work properly
from __future__ import annotations

import logging
from decimal import Decimal
from enum import Enum
from typing import Optional
from typing_extensions import Annotated

from sqlalchemy import String, JSON
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.schema import ForeignKey

from compendium_v2.db import db


logger = logging.getLogger(__name__)

str128 = Annotated[str, 128]
str128_pk = Annotated[str, mapped_column(String(128), primary_key=True)]
str256_pk = Annotated[str, mapped_column(String(256), primary_key=True)]
int_pk = Annotated[int, mapped_column(primary_key=True)]
int_pk_fkNREN = Annotated[int, mapped_column(ForeignKey("nren.id"), primary_key=True)]


# Unfortunately flask-sqlalchemy doesnt fully support DeclarativeBase yet.
# See https://github.com/pallets-eco/flask-sqlalchemy/issues/1140
# mypy: disable-error-code="name-defined"


class PreviewYear(db.Model):
    __tablename__ = 'preview_year'
    year: Mapped[int_pk]


class NREN(db.Model):
    __tablename__ = 'nren'
    id: Mapped[int_pk]
    name: Mapped[str128]
    country: Mapped[str128]


class BudgetEntry(db.Model):
    __tablename__ = 'budgets'
    nren_id: Mapped[int_pk_fkNREN]
    nren: Mapped[NREN] = relationship(lazy='joined')
    year: Mapped[int_pk]
    budget: Mapped[Decimal]


class FundingSource(db.Model):
    __tablename__ = 'funding_source'
    nren_id: Mapped[int_pk_fkNREN]
    nren: Mapped[NREN] = relationship(lazy='joined')
    year: Mapped[int_pk]
    client_institutions: Mapped[Decimal]
    european_funding: Mapped[Decimal]
    gov_public_bodies: Mapped[Decimal]
    commercial: Mapped[Decimal]
    other: Mapped[Decimal]


class FeeType(Enum):
    flat_fee = "flat_fee"
    usage_based_fee = "usage_based_fee"
    combination = "combination"
    no_charge = "no_charge"
    other = "other"


class ChargingStructure(db.Model):
    __tablename__ = 'charging_structure'
    nren_id: Mapped[int_pk_fkNREN]
    nren: Mapped[NREN] = relationship(lazy='joined')
    year: Mapped[int_pk]
    fee_type: Mapped[Optional[FeeType]]


class NrenStaff(db.Model):
    __tablename__ = 'nren_staff'
    nren_id: Mapped[int_pk_fkNREN]
    nren: Mapped[NREN] = relationship(lazy='joined')
    year: Mapped[int_pk]
    permanent_fte: Mapped[Decimal]
    subcontracted_fte: Mapped[Decimal]
    technical_fte: Mapped[Decimal]
    non_technical_fte: Mapped[Decimal]


class ParentOrganization(db.Model):
    __tablename__ = 'parent_organization'
    nren_id: Mapped[int_pk_fkNREN]
    nren: Mapped[NREN] = relationship(lazy='joined')
    year: Mapped[int_pk]
    organization: Mapped[str128]


class SubOrganization(db.Model):
    __tablename__ = 'sub_organization'
    nren_id: Mapped[int_pk_fkNREN]
    nren: Mapped[NREN] = relationship(lazy='joined')
    year: Mapped[int_pk]
    organization: Mapped[str128_pk]
    role: Mapped[str128]


class ECProject(db.Model):
    __tablename__ = 'ec_project'
    nren_id: Mapped[int_pk_fkNREN]
    nren: Mapped[NREN] = relationship(lazy='joined')
    year: Mapped[int_pk]
    project: Mapped[str256_pk]


class Policy(db.Model):
    __tablename__ = 'policy'
    nren_id: Mapped[int_pk_fkNREN]
    nren: Mapped[NREN] = relationship(lazy='joined')
    year: Mapped[int_pk]
    strategic_plan: Mapped[str]
    environmental: Mapped[str]
    equal_opportunity: Mapped[str]
    connectivity: Mapped[str]
    acceptable_use: Mapped[str]
    privacy_notice: Mapped[str]
    data_protection: Mapped[str]


class InstitutionURLs(db.Model):
    __tablename__ = 'institution_urls'

    nren_id: Mapped[int_pk_fkNREN]
    nren: Mapped[NREN] = relationship(lazy='joined')
    year: Mapped[int_pk]
    urls: Mapped[list[str]] = mapped_column(JSON)