DRRK/app/db/types.py

63 lines
2.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
from datetime import datetime
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
from sqlalchemy.orm import Mapped, mapped_column
from app.core.config import settings
# BIGINT в Postgres; в SQLite автоинкремент работает только у колонки ровно
# "INTEGER PRIMARY KEY" (алиас rowid), поэтому для локальной БД — Integer.
BigIntPK = sa.BigInteger().with_variant(sa.Integer(), "sqlite")
# JSONB в Postgres (индексируемый, компактный), обычный JSON в SQLite.
JsonType = sa.JSON().with_variant(postgresql.JSONB(), "postgresql")
# Деньги, цены, курсы — только Numeric. Точность с запасом: курсы ЦБ бывают
# с 8 знаками на единицу (VND), цены MOEX — до 6 знаков.
Price = sa.Numeric(18, 6)
Rate = sa.Numeric(18, 8)
Amount = sa.Numeric(20, 6)
Percent = sa.Numeric(12, 6)
Quantity = sa.Numeric(20, 4)
SYSTEM_USER = "system"
def qualified(table_column: str) -> str:
"""'currency.id' -> 'schema.currency.id', если задана DATABASE_SCHEMA.
Нужен для ForeignKey: при заданной схеме таблицы в metadata
регистрируются как 'schema.table', и FK без схемы не разрешится.
"""
if settings.DATABASE_SCHEMA:
return f"{settings.DATABASE_SCHEMA}.{table_column}"
return table_column
class IdMixin:
id: Mapped[int] = mapped_column(BigIntPK, sa.Identity(), primary_key=True)
class AuditMixin:
"""created_*/updated_* на всех таблицах.
Пользователь — email из профиля Keycloak, для джобов — SYSTEM_USER.
updated_at при upsert (INSERT ... ON CONFLICT) выставляется явно в
репозиториях: onupdate срабатывает только для ORM-UPDATE.
"""
created_at: Mapped[datetime] = mapped_column(
sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False
)
created_by: Mapped[str] = mapped_column(sa.String(255), nullable=False)
updated_at: Mapped[datetime] = mapped_column(
sa.DateTime(timezone=True),
server_default=sa.func.now(),
onupdate=sa.func.now(),
nullable=False,
)
updated_by: Mapped[str] = mapped_column(sa.String(255), nullable=False)