Compare commits

..

3 Commits

Author SHA1 Message Date
81a55ba452 Add fixtures; minor changes 2022-10-03 09:17:29 +02:00
cf83e0074e Expand courts/regsitry models 2022-08-29 21:06:33 +02:00
8cd13d8337 Consistently use DEFAULT_PK_TYPE 2022-08-17 15:03:41 +02:00
13 changed files with 277 additions and 41 deletions

View File

@ -10,6 +10,7 @@ from sqlalchemy.sql.schema import Column
from sqlalchemy.sql.sqltypes import TIMESTAMP
from sqlalchemy_utils.functions.orm import get_columns
from sqlalchemy_utils.listeners import force_auto_coercion
from sqlalchemy_utils.types.choice import Choice
from sqlmodel.main import Field, SQLModel
from compub.exceptions import NoDatabaseConfigured
@ -38,7 +39,7 @@ class DB:
force_auto_coercion()
@property
def engine(self):
def engine(self) -> Engine:
if self._engine is None:
self.start_engine()
assert isinstance(self._engine, (AsyncEngine, Engine))
@ -91,3 +92,7 @@ class AbstractBase(SQLModel):
@staticmethod
def get_non_repr_fields() -> list[str]:
return ['id', 'date_created', 'date_updated']
def get_choice_value(obj: Choice | str) -> str:
return obj.value if isinstance(obj, Choice) else obj

View File

@ -1,5 +1,5 @@
from datetime import date
from typing import Optional
from typing import Optional, TYPE_CHECKING
from slugify import slugify
from sqlalchemy.engine.base import Connection
@ -13,9 +13,12 @@ from sqlalchemy_utils.types import CountryType
from sqlmodel.main import Field, Relationship
from compub.utils import multi_max
from .base import AbstractBase
from .base import AbstractBase, DEFAULT_PK_TYPE as PK
from .geography import Address
if TYPE_CHECKING:
from .courts import RegisterNumber
__all__ = [
'LegalForm',
@ -33,7 +36,7 @@ class LegalForm(AbstractBase, table=True):
# Fields
short: str = Field(max_length=32, nullable=False, index=True)
name: Optional[str] = Field(default=None, max_length=255, sa_column=Column(Unicode(255)))
country: str = Field(sa_column=Column(CountryType))
country: Optional[str] = Field(sa_column=Column(CountryType))
# Relationships
subcategories: list['LegalFormSubcategory'] = Relationship(
@ -55,7 +58,7 @@ class LegalFormSubcategory(AbstractBase, table=True):
name: Optional[str] = Field(default=None, max_length=255, sa_column=Column(Unicode(255)))
# Relationships
legal_form_id: Optional[int] = Field(
legal_form_id: Optional[PK] = Field(
foreign_key='legal_form.id', default=None, nullable=False, index=True
)
legal_form: Optional[LegalForm] = Relationship(
@ -77,8 +80,8 @@ class CompanyIndustryLink(AbstractBase, table=True):
)
# Relationships
company_id: Optional[int] = Field(foreign_key='company.id', default=None, nullable=False, primary_key=True)
industry_id: Optional[int] = Field(foreign_key='industry.id', default=None, nullable=False, primary_key=True)
company_id: Optional[PK] = Field(foreign_key='company.id', default=None, nullable=False, primary_key=True)
industry_id: Optional[PK] = Field(foreign_key='industry.id', default=None, nullable=False, primary_key=True)
class CompanyExecutiveLink(AbstractBase, table=True):
@ -88,8 +91,8 @@ class CompanyExecutiveLink(AbstractBase, table=True):
)
# Relationships
company_id: Optional[int] = Field(foreign_key='company.id', default=None, nullable=False, primary_key=True)
executive_id: Optional[int] = Field(foreign_key='executive.id', default=None, nullable=False, primary_key=True)
company_id: Optional[PK] = Field(foreign_key='company.id', default=None, nullable=False, primary_key=True)
executive_id: Optional[PK] = Field(foreign_key='executive.id', default=None, nullable=False, primary_key=True)
class Industry(AbstractBase, table=True):
@ -137,14 +140,14 @@ class Company(AbstractBase, table=True):
city: Optional[str] = Field(max_length=255, nullable=True, index=True)
# Relationships
legal_form_id: Optional[int] = Field(
legal_form_id: Optional[PK] = Field(
foreign_key='legal_form_subcategory.id', default=None, index=True
)
legal_form: Optional[LegalFormSubcategory] = Relationship(
back_populates='companies', sa_relationship_kwargs={'lazy': 'selectin'}
)
address_id: Optional[int] = Field(
address_id: Optional[PK] = Field(
foreign_key='address.id', default=None, index=True
)
address: Optional[Address] = Relationship(
@ -163,6 +166,10 @@ class Company(AbstractBase, table=True):
back_populates='company', sa_relationship_kwargs={'lazy': 'selectin'}
)
register_numbers: list['RegisterNumber'] = Relationship(
back_populates='company', sa_relationship_kwargs={'lazy': 'selectin'}
)
def __str__(self) -> str:
return str(self.current_name or f"<Company {self.id}>")
@ -188,7 +195,7 @@ class CompanyName(AbstractBase, table=True):
slug: Optional[str] = Field(default=None, max_length=__MAX_SLUG_LENGTH__, index=True)
# Relationships
company_id: Optional[int] = Field(
company_id: Optional[PK] = Field(
foreign_key='company.id', default=None, nullable=False, index=True
)
company: Optional[Company] = Relationship(

View File

@ -1,24 +1,43 @@
from enum import Enum as EnumPy
from typing import Optional
from sqlalchemy.sql.schema import Column, Index
from sqlalchemy.sql.sqltypes import Unicode
from sqlalchemy.sql.sqltypes import Unicode, Enum as EnumSQL
from sqlmodel.main import Field, Relationship
from .base import AbstractBase, DEFAULT_PK_TYPE
from .base import AbstractBase, DEFAULT_PK_TYPE as PK
from .companies import Company
from .geography import StateProvince, Address
__all__ = [
'CourtClass',
'CourtDepartment',
'Court',
'RegisterBranch',
'RegisterNumber',
]
# 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)))
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'}
back_populates='court_class',
sa_relationship_kwargs={'lazy': 'selectin'}
)
def __str__(self) -> str:
@ -32,11 +51,17 @@ class CourtDepartmentCourtLink(AbstractBase, table=True):
)
# Relationships
court_department_id: Optional[DEFAULT_PK_TYPE] = Field(
foreign_key='court_department.id', default=None, nullable=False, primary_key=True
court_department_id: Optional[PK] = 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
court_id: Optional[PK] = Field(
foreign_key='court.id',
default=None,
nullable=False,
primary_key=True
)
@ -48,11 +73,15 @@ class CourtDepartment(AbstractBase, table=True):
__INS_COURT_PK__ = 2
# Fields
name: str = Field(max_length=255, sa_column=Column(Unicode(255)))
name: str = Field(
max_length=255,
sa_column=Column(Unicode(255))
)
# Relationships
courts: list['Court'] = Relationship(
back_populates='court_departments', link_model=CourtDepartmentCourtLink,
back_populates='court_departments',
link_model=CourtDepartmentCourtLink,
sa_relationship_kwargs={'lazy': 'selectin'}
)
@ -64,32 +93,50 @@ class Court(AbstractBase, table=True):
__tablename__ = 'court'
# Fields
name: str = Field(max_length=255, sa_column=Column(Unicode(255)))
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_id: Optional[PK] = 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'}
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_id: Optional[PK] = 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'}
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_id: Optional[PK] = Field(
foreign_key='address.id',
default=None,
nullable=True,
index=True
)
address: Optional[Address] = Relationship(
back_populates='courts', sa_relationship_kwargs={'lazy': 'selectin'}
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_id: Optional[PK] = Field(
foreign_key='court.id',
default=None,
nullable=True,
index=True
)
parent_court: Optional['Court'] = Relationship(
back_populates='sub_courts',
@ -99,12 +146,89 @@ class Court(AbstractBase, table=True):
)
)
sub_courts: list['Court'] = Relationship(
back_populates='parent_court', sa_relationship_kwargs={'lazy': 'selectin'}
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'}
back_populates='courts',
link_model=CourtDepartmentCourtLink,
sa_relationship_kwargs={'lazy': 'selectin'}
)
register_numbers: list['RegisterNumber'] = Relationship(
back_populates='court', sa_relationship_kwargs={'lazy': 'selectin'}
)
def __str__(self) -> str:
return str(self.name)
class RegisterBranch(str, EnumPy):
HRA = 'HRA'
HRB = 'HRB'
GnR = 'GnR'
PR = 'PR'
VR = 'VR'
class RegisterNumber(AbstractBase, table=True):
__tablename__ = 'register_number'
# Fields
branch: Optional[RegisterBranch] = Field(
default=None,
sa_column=Column(
EnumSQL(RegisterBranch),
nullable=True,
index=True
)
)
number: str = Field(
max_length=255,
index=True
)
suffix: Optional[str] = Field(
max_length=4,
nullable=True
)
ureg_company_id: Optional[int] = Field(
nullable=True,
index=True
)
# Relationships
court_id: Optional[PK] = Field(
foreign_key='court.id',
default=None,
index=True
)
court: Optional[Court] = Relationship(
back_populates='register_numbers',
sa_relationship_kwargs=dict(
lazy='selectin'
)
)
company_id: Optional[PK] = Field(
foreign_key='company.id',
default=None,
index=True
)
company: Optional[Company] = Relationship(
back_populates='register_numbers',
sa_relationship_kwargs=dict(
lazy='selectin'
)
)
def __str__(self) -> str:
return f'{self.with_branch_code} ({self.company.current_name})'
@property
def with_branch_code(self) -> str:
return f'{self.branch} {self.number}' if self.branch else str(self.number)
@property
def verbose_id(self) -> str:
return f'{self.court} {self.with_branch_code}'

View File

@ -7,7 +7,7 @@ from sqlalchemy_utils.primitives.country import Country
from sqlalchemy_utils.types import CountryType
from sqlmodel.main import Field, Relationship
from .base import AbstractBase
from .base import AbstractBase, DEFAULT_PK_TYPE as PK
if TYPE_CHECKING:
from .companies import Company
@ -61,7 +61,7 @@ class City(AbstractBase, table=True):
name: str = Field(max_length=255, sa_column=Column(Unicode(255), nullable=False, index=True))
# Relationships
state_province_id: Optional[int] = Field(
state_province_id: Optional[PK] = Field(
foreign_key='state_province.id', default=None, nullable=False, index=True
)
state_province: Optional[StateProvince] = Relationship(
@ -80,7 +80,7 @@ class Street(AbstractBase, table=True):
name: str = Field(max_length=255, sa_column=Column(Unicode(255), nullable=False, index=True))
# Relationships
city_id: Optional[int] = Field(
city_id: Optional[PK] = Field(
foreign_key='city.id', default=None, nullable=False, index=True
)
city: Optional[City] = Relationship(
@ -100,7 +100,7 @@ class Address(AbstractBase, table=True):
supplement: str = Field(max_length=255)
# Relationships
street_id: Optional[int] = Field(
street_id: Optional[PK] = Field(
foreign_key='street.id', default=None, nullable=False, index=True
)
street: Optional[Street] = Relationship(

5
tests/fixtures/companies/company.json vendored Normal file
View File

@ -0,0 +1,5 @@
[
{
}
]

View File

View File

@ -0,0 +1,9 @@
[
{
"id": 1,
"name": "Energy"
}, {
"id": 2,
"name": "Retail"
}
]

View File

@ -0,0 +1,16 @@
[
{
"id": 1,
"short": "KG",
"name": "Kommanditgesellschaft",
"country": "DE"
}, {
"id": 2,
"short": "AG",
"name": "Aktiengesellschaft",
"country": "DE"
}, {
"id": 123,
"short": "Ausl.HRB"
}
]

View File

@ -0,0 +1,17 @@
[
{
"id": 111,
"short": "GmbH & Co. KG",
"name": "Gesellschaft mit beschränkter Haftung & Compagnie Kommanditgesellschaft",
"legal_form_id": 1
}, {
"id": 112,
"short": "AG & Co. KG",
"name": "Aktiengesellschaft & Compagnie Kommanditgesellschaft",
"legal_form_id": 1
}, {
"id": 69420,
"short": "LLC",
"legal_form_id": 123
}
]

8
tests/fixtures/geography/address.json vendored Normal file
View File

@ -0,0 +1,8 @@
[
{
"id": 9999999,
"house_number": "123AB",
"supplement": "whatever",
"street_id": 1
}
]

23
tests/fixtures/geography/city.json vendored Normal file
View File

@ -0,0 +1,23 @@
[
{
"id": 1122,
"zip_code": "10405",
"name": "Berlin",
"state_province_id": 100
}, {
"id": 9,
"zip_code": "33299",
"name": "Miami",
"state_province_id": 30
}, {
"id": 10,
"zip_code": "33694",
"name": "Tampa",
"state_province_id": 30
}, {
"id": 78787878,
"zip_code": "91000",
"name": "Luhansk",
"state_province_id": 4531354
}
]

View File

@ -0,0 +1,15 @@
[
{
"id": 100,
"country": "DE",
"name": "Berlin"
}, {
"id": 30,
"country": "US",
"name": "Florida"
}, {
"id": 4531354,
"country": "UA",
"name": "Luhansk Oblast"
}
]

7
tests/fixtures/geography/street.json vendored Normal file
View File

@ -0,0 +1,7 @@
[
{
"id": 1,
"name": "Some Street",
"city_id": 1122
}
]