generated from daniil-berg/boilerplate-py
95 lines
2.7 KiB
Python
95 lines
2.7 KiB
Python
from typing import Any, Optional
|
|
|
|
from pydantic import validator
|
|
from sqlalchemy.sql.schema import Column
|
|
from sqlalchemy.sql.sqltypes import Unicode
|
|
from sqlalchemy_utils.primitives.country import Country
|
|
from sqlalchemy_utils.types import CountryType
|
|
from sqlmodel.main import Field, Relationship
|
|
|
|
from .base import AbstractBase
|
|
|
|
|
|
__all__ = [
|
|
'StateProvince',
|
|
'City',
|
|
'Street',
|
|
'Address',
|
|
]
|
|
|
|
|
|
class StateProvince(AbstractBase, table=True):
|
|
__tablename__ = 'state_province'
|
|
|
|
# Fields
|
|
country: str = Field(sa_column=Column(CountryType, nullable=False, index=True))
|
|
name: str = Field(max_length=255, sa_column=Column(Unicode(255), nullable=False, index=True))
|
|
|
|
# Relationships
|
|
cities: list['City'] = 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):
|
|
return v.code
|
|
if isinstance(v, str):
|
|
return v.upper()
|
|
raise TypeError
|
|
|
|
|
|
class City(AbstractBase, table=True):
|
|
__tablename__ = 'city'
|
|
|
|
# Fields
|
|
zip_code: str = Field(max_length=5, nullable=False, index=True)
|
|
name: str = Field(max_length=255, sa_column=Column(Unicode(255), nullable=False, index=True))
|
|
|
|
# Relationships
|
|
state_province_id: Optional[int] = Field(
|
|
foreign_key='state_province.id', default=None, nullable=False, index=True
|
|
)
|
|
state_province: Optional[StateProvince] = Relationship(
|
|
back_populates='cities', sa_relationship_kwargs={'lazy': 'selectin'}
|
|
)
|
|
|
|
streets: list['Street'] = Relationship(
|
|
back_populates='city', sa_relationship_kwargs={'lazy': 'selectin'}
|
|
)
|
|
|
|
|
|
class Street(AbstractBase, table=True):
|
|
__tablename__ = 'street'
|
|
|
|
# Fields
|
|
name: str = Field(max_length=255, sa_column=Column(Unicode(255), nullable=False, index=True))
|
|
|
|
# Relationships
|
|
city_id: Optional[int] = Field(
|
|
foreign_key='city.id', default=None, nullable=False, index=True
|
|
)
|
|
city: Optional[City] = Relationship(
|
|
back_populates='streets', sa_relationship_kwargs={'lazy': 'selectin'}
|
|
)
|
|
|
|
addresses: list['Address'] = Relationship(
|
|
back_populates='street', sa_relationship_kwargs={'lazy': 'selectin'}
|
|
)
|
|
|
|
|
|
class Address(AbstractBase, table=True):
|
|
__tablename__ = 'address'
|
|
|
|
# Fields
|
|
house_number: str = Field(max_length=8, nullable=False)
|
|
supplement: str = Field(max_length=255)
|
|
|
|
# Relationships
|
|
street_id: Optional[int] = Field(
|
|
foreign_key='street.id', default=None, nullable=False, index=True
|
|
)
|
|
street: Optional[Street] = Relationship(
|
|
back_populates='addresses', sa_relationship_kwargs={'lazy': 'selectin'}
|
|
)
|