diff --git a/src/compub/models/base.py b/src/compub/models/base.py index 587e3c1..3754302 100644 --- a/src/compub/models/base.py +++ b/src/compub/models/base.py @@ -18,6 +18,9 @@ from compub.settings import settings from sqlmodel import create_engine, Session +DEFAULT_PK_TYPE = int + + class DB: def __init__(self): self._engine: AsyncEngine | Engine | None = None @@ -63,7 +66,7 @@ class DB: class AbstractBase(SQLModel): - id: Optional[int] = Field(default=None, primary_key=True) + id: Optional[DEFAULT_PK_TYPE] = Field(default=None, primary_key=True) date_created: Optional[datetime] = Field( default=None, sa_column=Column(TIMESTAMP(timezone=False), server_default=db_now()) ) diff --git a/src/compub/models/companies.py b/src/compub/models/companies.py index 5c7b94a..0d2dd33 100644 --- a/src/compub/models/companies.py +++ b/src/compub/models/companies.py @@ -14,6 +14,7 @@ from sqlmodel.main import Field, Relationship from compub.utils import multi_max from .base import AbstractBase +from .geography import Address __all__ = [ @@ -146,6 +147,9 @@ class Company(AbstractBase, table=True): address_id: Optional[int] = Field( foreign_key='address.id', default=None, index=True ) + address: Optional[Address] = Relationship( + back_populates='companies', sa_relationship_kwargs={'lazy': 'selectin'} + ) industries: list[Industry] = Relationship( back_populates='companies', link_model=CompanyIndustryLink, sa_relationship_kwargs={'lazy': 'selectin'} diff --git a/src/compub/models/courts.py b/src/compub/models/courts.py new file mode 100644 index 0000000..2eb76ce --- /dev/null +++ b/src/compub/models/courts.py @@ -0,0 +1,110 @@ +from typing import Optional + +from sqlalchemy.sql.schema import Column, Index +from sqlalchemy.sql.sqltypes import Unicode +from sqlmodel.main import Field, Relationship + +from .base import AbstractBase, DEFAULT_PK_TYPE +from .geography import StateProvince, Address + + +# Amtsgericht -> Landgericht -> OLG -> BGH +class CourtClass(AbstractBase, table=True): + __tablename__ = 'court_class' + + # Fields + short: str = Field(max_length=32, nullable=False, index=True) + name: str = Field(max_length=255, sa_column=Column(Unicode(255))) + + # Relationships + courts: list['Court'] = Relationship( + back_populates='court_class', sa_relationship_kwargs={'lazy': 'selectin'} + ) + + def __str__(self) -> str: + return str(self.name) + + +class CourtDepartmentCourtLink(AbstractBase, table=True): + __tablename__ = 'court_department_court' + __table_args__ = ( + Index('ux_court_department_court', 'court_department_id', 'court_id', unique=True), + ) + + # Relationships + court_department_id: Optional[DEFAULT_PK_TYPE] = Field( + foreign_key='court_department.id', default=None, nullable=False, primary_key=True + ) + court_id: Optional[DEFAULT_PK_TYPE] = Field( + foreign_key='court.id', default=None, nullable=False, primary_key=True + ) + + +# Abteilung innerhalb eines Amtsgerichts (z. B. Registergericht, Insolvenzgericht etc.) +class CourtDepartment(AbstractBase, table=True): + __tablename__ = 'court_department' + + __REG_COURT_PK__ = 1 + __INS_COURT_PK__ = 2 + + # Fields + name: str = Field(max_length=255, sa_column=Column(Unicode(255))) + + # Relationships + courts: list['Court'] = Relationship( + back_populates='court_departments', link_model=CourtDepartmentCourtLink, + sa_relationship_kwargs={'lazy': 'selectin'} + ) + + def __str__(self) -> str: + return str(self.name) + + +class Court(AbstractBase, table=True): + __tablename__ = 'court' + + # Fields + name: str = Field(max_length=255, sa_column=Column(Unicode(255))) + + # Relationships + court_class_id: Optional[DEFAULT_PK_TYPE] = Field( + foreign_key='court_class.id', default=None, nullable=False, index=True + ) + court_class: Optional[CourtClass] = Relationship( + back_populates='courts', sa_relationship_kwargs={'lazy': 'selectin'} + ) + + state_province_id: Optional[DEFAULT_PK_TYPE] = Field( + foreign_key='state_province.id', default=None, nullable=True, index=True + ) + state_province: Optional[StateProvince] = Relationship( + back_populates='courts', sa_relationship_kwargs={'lazy': 'selectin'} + ) + + address_id: Optional[DEFAULT_PK_TYPE] = Field( + foreign_key='address.id', default=None, nullable=True, index=True + ) + address: Optional[Address] = Relationship( + back_populates='courts', sa_relationship_kwargs={'lazy': 'selectin'} + ) + + parent_court_id: Optional[DEFAULT_PK_TYPE] = Field( + foreign_key='court.id', default=None, nullable=True, index=True + ) + parent_court: Optional['Court'] = Relationship( + back_populates='sub_courts', + sa_relationship_kwargs=dict( + lazy='selectin', + remote_side='Court.id' + ) + ) + sub_courts: list['Court'] = Relationship( + back_populates='parent_court', sa_relationship_kwargs={'lazy': 'selectin'} + ) + + court_departments: list[CourtDepartment] = Relationship( + back_populates='courts', link_model=CourtDepartmentCourtLink, sa_relationship_kwargs={'lazy': 'selectin'} + ) + + def __str__(self) -> str: + return str(self.name) diff --git a/src/compub/models/geography.py b/src/compub/models/geography.py index db52591..7829064 100644 --- a/src/compub/models/geography.py +++ b/src/compub/models/geography.py @@ -1,4 +1,4 @@ -from typing import Any, Optional +from typing import Any, Optional, TYPE_CHECKING from pydantic import validator from sqlalchemy.sql.schema import Column, Index @@ -9,6 +9,10 @@ from sqlmodel.main import Field, Relationship from .base import AbstractBase +if TYPE_CHECKING: + from .companies import Company + from .courts import Court + __all__ = [ 'StateProvince', @@ -33,6 +37,10 @@ class StateProvince(AbstractBase, table=True): back_populates='state_province', sa_relationship_kwargs={'lazy': 'selectin'} ) + courts: list['Court'] = Relationship( + back_populates='state_province', sa_relationship_kwargs={'lazy': 'selectin'} + ) + @validator('country', pre=True) def country_as_uppercase_string(cls, v: Any) -> str: if isinstance(v, Country): @@ -98,3 +106,11 @@ class Address(AbstractBase, table=True): street: Optional[Street] = Relationship( back_populates='addresses', sa_relationship_kwargs={'lazy': 'selectin'} ) + + companies: list['Company'] = Relationship( + back_populates='address', sa_relationship_kwargs={'lazy': 'selectin'} + ) + + courts: list['Court'] = Relationship( + back_populates='address', sa_relationship_kwargs={'lazy': 'selectin'} + )