Skip to content
Snippets Groups Projects
Commit 3c3fb6ac authored by Remco Tukker's avatar Remco Tukker
Browse files

upgraded to fully typed sqlalchemy

parent f35706b9
Branches
Tags
1 merge request!12Feature/comp 114 python code quality
import enum
import logging import logging
from typing import Any from decimal import Decimal
from enum import Enum
from typing import Optional
from typing_extensions import Annotated
from sqlalchemy import Column, Enum, Integer, MetaData, Numeric, String from sqlalchemy import MetaData, String
from sqlalchemy.orm import relationship, declarative_base from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from sqlalchemy.schema import ForeignKey from sqlalchemy.schema import ForeignKey
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
convention = { convention = {
...@@ -18,37 +21,45 @@ convention = { ...@@ -18,37 +21,45 @@ convention = {
metadata_obj = MetaData(naming_convention=convention) metadata_obj = MetaData(naming_convention=convention)
# https://github.com/python/mypy/issues/2477 str128 = Annotated[str, 128]
base_schema: Any = declarative_base(metadata=metadata_obj) int_pk = Annotated[int, mapped_column(primary_key=True)]
int_pk_fkNREN = Annotated[int, mapped_column(ForeignKey("nren.id"), primary_key=True)]
class Base(DeclarativeBase):
metadata = metadata_obj
type_annotation_map = {
str128: String(128),
}
class NREN(base_schema): class NREN(Base):
__tablename__ = 'nren' __tablename__ = 'nren'
id = Column(Integer, primary_key=True) id: Mapped[int_pk]
name = Column(String(128), nullable=False) name: Mapped[str128]
class BudgetEntry(base_schema): class BudgetEntry(Base):
__tablename__ = 'budgets' __tablename__ = 'budgets'
nren_id = Column(Integer, ForeignKey(NREN.id), primary_key=True) nren_id: Mapped[int_pk_fkNREN]
nren = relationship(NREN, lazy='joined') nren: Mapped[NREN] = relationship(lazy='joined')
year = Column(Integer, primary_key=True) year: Mapped[int_pk]
budget = Column(Numeric(asdecimal=False), nullable=False) budget: Mapped[Decimal]
class FundingSource(base_schema): class FundingSource(Base):
__tablename__ = 'funding_source' __tablename__ = 'funding_source'
nren_id = Column(Integer, ForeignKey(NREN.id), primary_key=True) nren_id: Mapped[int_pk_fkNREN]
nren = relationship(NREN, lazy='joined') nren: Mapped[NREN] = relationship(lazy='joined')
year = Column(Integer, primary_key=True) year: Mapped[int_pk]
client_institutions = Column(Numeric(asdecimal=False), nullable=False) client_institutions: Mapped[Decimal]
european_funding = Column(Numeric(asdecimal=False), nullable=False) european_funding: Mapped[Decimal]
gov_public_bodies = Column(Numeric(asdecimal=False), nullable=False) gov_public_bodies: Mapped[Decimal]
commercial = Column(Numeric(asdecimal=False), nullable=False) commercial: Mapped[Decimal]
other = Column(Numeric(asdecimal=False), nullable=False) other: Mapped[Decimal]
class FeeType(enum.Enum): class FeeType(Enum):
flat_fee = "flat_fee" flat_fee = "flat_fee"
usage_based_fee = "usage_based_fee" usage_based_fee = "usage_based_fee"
combination = "combination" combination = "combination"
...@@ -56,45 +67,45 @@ class FeeType(enum.Enum): ...@@ -56,45 +67,45 @@ class FeeType(enum.Enum):
other = "other" other = "other"
class ChargingStructure(base_schema): class ChargingStructure(Base):
__tablename__ = 'charging_structure' __tablename__ = 'charging_structure'
nren_id = Column(Integer, ForeignKey(NREN.id), primary_key=True) nren_id: Mapped[int_pk_fkNREN]
nren = relationship(NREN, lazy='joined') nren: Mapped[NREN] = relationship(lazy='joined')
year = Column(Integer, primary_key=True) year: Mapped[int_pk]
fee_type = Column('fee_type', Enum(FeeType, name="fee_type"), nullable=True) fee_type: Mapped[Optional[FeeType]]
class NrenStaff(base_schema): class NrenStaff(Base):
__tablename__ = 'nren_staff' __tablename__ = 'nren_staff'
nren_id = Column(Integer, ForeignKey(NREN.id), primary_key=True) nren_id: Mapped[int_pk_fkNREN]
nren = relationship(NREN, lazy='joined') nren: Mapped[NREN] = relationship(lazy='joined')
year = Column(Integer, primary_key=True) year: Mapped[int_pk]
permanent_fte = Column(Numeric(asdecimal=False), nullable=False) permanent_fte: Mapped[Decimal]
subcontracted_fte = Column(Numeric(asdecimal=False), nullable=False) subcontracted_fte: Mapped[Decimal]
technical_fte = Column(Numeric(asdecimal=False), nullable=False) technical_fte: Mapped[Decimal]
non_technical_fte = Column(Numeric(asdecimal=False), nullable=False) non_technical_fte: Mapped[Decimal]
class ParentOrganization(base_schema): class ParentOrganization(Base):
__tablename__ = 'parent_organization' __tablename__ = 'parent_organization'
nren_id = Column(Integer, ForeignKey(NREN.id), primary_key=True) nren_id: Mapped[int_pk_fkNREN]
nren = relationship(NREN, lazy='joined') nren: Mapped[NREN] = relationship(lazy='joined')
year = Column(Integer, primary_key=True) year: Mapped[int_pk]
organization = Column(String(128), nullable=False) organization: Mapped[str128]
class SubOrganization(base_schema): class SubOrganization(Base):
__tablename__ = 'sub_organization' __tablename__ = 'sub_organization'
nren_id = Column(Integer, ForeignKey(NREN.id), primary_key=True) nren_id: Mapped[int_pk_fkNREN]
nren = relationship(NREN, lazy='joined') nren: Mapped[NREN] = relationship(lazy='joined')
year = Column(Integer, primary_key=True) year: Mapped[int_pk]
organization = Column(String(128), primary_key=True) organization: Mapped[str128] = mapped_column(primary_key=True)
role = Column(String(128), nullable=False) role: Mapped[str128]
class ECProject(base_schema): class ECProject(Base):
__tablename__ = 'ec_project' __tablename__ = 'ec_project'
nren_id = Column(Integer, ForeignKey(NREN.id), primary_key=True) nren_id: Mapped[int_pk_fkNREN]
nren = relationship(NREN, lazy='joined') nren: Mapped[NREN] = relationship(NREN, lazy='joined')
year = Column(Integer, primary_key=True) year: Mapped[int_pk]
project = Column(String(256), primary_key=True) project: Mapped[str] = mapped_column(String(256), primary_key=True)
Single-database configuration for Flask.
...@@ -62,7 +62,7 @@ def funding_source_view() -> Any: ...@@ -62,7 +62,7 @@ def funding_source_view() -> Any:
def _extract_data(entry: model.FundingSource): def _extract_data(entry: model.FundingSource):
return { return {
'NREN': entry.nren.name, 'NREN': entry.nren.name,
'YEAR': int(entry.year), 'YEAR': entry.year,
'CLIENT_INSTITUTIONS': float(entry.client_institutions), 'CLIENT_INSTITUTIONS': float(entry.client_institutions),
'EUROPEAN_FUNDING': float(entry.european_funding), 'EUROPEAN_FUNDING': float(entry.european_funding),
'GOV_PUBLIC_BODIES': float(entry.gov_public_bodies), 'GOV_PUBLIC_BODIES': float(entry.gov_public_bodies),
......
...@@ -61,10 +61,10 @@ def staff_view() -> Any: ...@@ -61,10 +61,10 @@ def staff_view() -> Any:
return { return {
'nren': entry.nren.name, 'nren': entry.nren.name,
'year': entry.year, 'year': entry.year,
'permanent_fte': entry.permanent_fte, 'permanent_fte': float(entry.permanent_fte),
'subcontracted_fte': entry.subcontracted_fte, 'subcontracted_fte': float(entry.subcontracted_fte),
'technical_fte': entry.technical_fte, 'technical_fte': float(entry.technical_fte),
'non_technical_fte': entry.non_technical_fte 'non_technical_fte': float(entry.non_technical_fte)
} }
with db.session_scope() as session: with db.session_scope() as session:
......
import logging import logging
from typing import List, Optional
from typing import Any from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy.schema import ForeignKey from sqlalchemy.schema import ForeignKey
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# https://github.com/python/mypy/issues/2477
base_schema: Any = declarative_base() class Base(DeclarativeBase):
pass
class Budgets(base_schema): class Budgets(Base):
__tablename__ = 'budgets' __tablename__ = 'budgets'
id = Column(Integer, primary_key=True) id: Mapped[int] = mapped_column(primary_key=True)
budget = Column(String) budget: Mapped[Optional[str]]
year = Column(Integer) year: Mapped[Optional[int]]
country_code = Column('country_code', String, ForeignKey('nrens.country_code')) country_code: Mapped[Optional[str]] = mapped_column(ForeignKey('nrens.country_code'))
nren = relationship('Nrens', back_populates='budgets') nren: Mapped[Optional['Nrens']] = relationship(back_populates='budgets')
class Nrens(base_schema): class Nrens(Base):
__tablename__ = 'nrens' __tablename__ = 'nrens'
id = Column(Integer, primary_key=True) id: Mapped[int] = mapped_column(primary_key=True)
abbreviation = Column(String) abbreviation: Mapped[Optional[str]]
country_code = Column(String) country_code: Mapped[Optional[str]]
budgets = relationship('Budgets', back_populates='nren') budgets: Mapped[List['Budgets']] = relationship(back_populates='nren')
...@@ -40,7 +40,7 @@ def mocked_survey_db(mocker): ...@@ -40,7 +40,7 @@ def mocked_survey_db(mocker):
connect_args={'check_same_thread': False}, connect_args={'check_same_thread': False},
poolclass=StaticPool, poolclass=StaticPool,
echo=False) echo=False)
survey_model.base_schema.metadata.create_all(engine) survey_model.Base.metadata.create_all(engine)
mocker.patch( mocker.patch(
'compendium_v2.survey_db._SESSION_MAKER', 'compendium_v2.survey_db._SESSION_MAKER',
sessionmaker(bind=engine)) sessionmaker(bind=engine))
...@@ -57,7 +57,7 @@ def mocked_db(mocker): ...@@ -57,7 +57,7 @@ def mocked_db(mocker):
connect_args={'check_same_thread': False}, connect_args={'check_same_thread': False},
poolclass=StaticPool, poolclass=StaticPool,
echo=False) echo=False)
model.base_schema.metadata.create_all(engine) model.Base.metadata.create_all(engine)
mocker.patch( mocker.patch(
'compendium_v2.db._SESSION_MAKER', 'compendium_v2.db._SESSION_MAKER',
sessionmaker(bind=engine)) sessionmaker(bind=engine))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment