mirror of
https://github.com/wowlikon/LiB.git
synced 2026-02-04 04:31:09 +00:00
Динамическое создание er-диаграммы по моделям
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
"""Модуль DB-моделей авторов"""
|
||||
|
||||
from typing import TYPE_CHECKING, List
|
||||
|
||||
from sqlmodel import Field, Relationship
|
||||
@@ -12,7 +13,10 @@ if TYPE_CHECKING:
|
||||
|
||||
class Author(AuthorBase, table=True):
|
||||
"""Модель автора в базе данных"""
|
||||
id: int | None = Field(default=None, primary_key=True, index=True)
|
||||
|
||||
id: int | None = Field(
|
||||
default=None, primary_key=True, index=True, description="Идентификатор"
|
||||
)
|
||||
books: List["Book"] = Relationship(
|
||||
back_populates="authors", link_model=AuthorBookLink
|
||||
)
|
||||
|
||||
@@ -17,10 +17,13 @@ if TYPE_CHECKING:
|
||||
class Book(BookBase, table=True):
|
||||
"""Модель книги в базе данных"""
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True, index=True)
|
||||
id: int | None = Field(
|
||||
default=None, primary_key=True, index=True, description="Идентификатор"
|
||||
)
|
||||
status: BookStatus = Field(
|
||||
default=BookStatus.ACTIVE,
|
||||
sa_column=Column(String, nullable=False, default="active"),
|
||||
description="Статус",
|
||||
)
|
||||
authors: List["Author"] = Relationship(
|
||||
back_populates="books", link_model=AuthorBookLink
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Модуль DB-моделей жанров"""
|
||||
|
||||
from typing import TYPE_CHECKING, List
|
||||
|
||||
from sqlmodel import Field, Relationship
|
||||
@@ -12,7 +13,10 @@ if TYPE_CHECKING:
|
||||
|
||||
class Genre(GenreBase, table=True):
|
||||
"""Модель жанра в базе данных"""
|
||||
id: int | None = Field(default=None, primary_key=True, index=True)
|
||||
|
||||
id: int | None = Field(
|
||||
default=None, primary_key=True, index=True, description="Идентификатор"
|
||||
)
|
||||
books: List["Book"] = Relationship(
|
||||
back_populates="genres", link_model=GenreBookLink
|
||||
)
|
||||
|
||||
@@ -10,14 +10,29 @@ class AuthorBookLink(SQLModel, table=True):
|
||||
author_id: int | None = Field(
|
||||
default=None, foreign_key="author.id", primary_key=True
|
||||
)
|
||||
book_id: int | None = Field(default=None, foreign_key="book.id", primary_key=True)
|
||||
book_id: int | None = Field(
|
||||
default=None,
|
||||
foreign_key="book.id",
|
||||
primary_key=True,
|
||||
description="Идентификатор книги",
|
||||
)
|
||||
|
||||
|
||||
class GenreBookLink(SQLModel, table=True):
|
||||
"""Модель связи жанра и книги"""
|
||||
|
||||
genre_id: int | None = Field(default=None, foreign_key="genre.id", primary_key=True)
|
||||
book_id: int | None = Field(default=None, foreign_key="book.id", primary_key=True)
|
||||
genre_id: int | None = Field(
|
||||
default=None,
|
||||
foreign_key="genre.id",
|
||||
primary_key=True,
|
||||
description="Идентификатор жанра",
|
||||
)
|
||||
book_id: int | None = Field(
|
||||
default=None,
|
||||
foreign_key="book.id",
|
||||
primary_key=True,
|
||||
description="Идентификатор книги",
|
||||
)
|
||||
|
||||
|
||||
class UserRoleLink(SQLModel, table=True):
|
||||
@@ -25,8 +40,18 @@ class UserRoleLink(SQLModel, table=True):
|
||||
|
||||
__tablename__ = "user_roles"
|
||||
|
||||
user_id: int | None = Field(default=None, foreign_key="users.id", primary_key=True)
|
||||
role_id: int | None = Field(default=None, foreign_key="roles.id", primary_key=True)
|
||||
user_id: int | None = Field(
|
||||
default=None,
|
||||
foreign_key="users.id",
|
||||
primary_key=True,
|
||||
description="Идентификатор пользователя",
|
||||
)
|
||||
role_id: int | None = Field(
|
||||
default=None,
|
||||
foreign_key="roles.id",
|
||||
primary_key=True,
|
||||
description="Идентификатор роли",
|
||||
)
|
||||
|
||||
|
||||
class BookUserLink(SQLModel, table=True):
|
||||
@@ -35,13 +60,22 @@ class BookUserLink(SQLModel, table=True):
|
||||
Связывает книгу и пользователя с фиксацией времени.
|
||||
"""
|
||||
|
||||
__tablename__ = "book_loans"
|
||||
__tablename__ = "loans"
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True, index=True)
|
||||
id: int | None = Field(
|
||||
default=None, primary_key=True, index=True, description="Идентификатор"
|
||||
)
|
||||
|
||||
book_id: int = Field(foreign_key="book.id")
|
||||
user_id: int = Field(foreign_key="users.id")
|
||||
book_id: int = Field(foreign_key="book.id", description="Идентификатор")
|
||||
user_id: int = Field(
|
||||
foreign_key="users.id", description="Идентификатор пользователя"
|
||||
)
|
||||
|
||||
borrowed_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
||||
due_date: datetime
|
||||
returned_at: datetime | None = Field(default=None)
|
||||
borrowed_at: datetime = Field(
|
||||
default_factory=lambda: datetime.now(timezone.utc),
|
||||
description="Дата и время выдачи",
|
||||
)
|
||||
due_date: datetime = Field(description="Дата и время запланированного возврата")
|
||||
returned_at: datetime | None = Field(
|
||||
default=None, description="Дата и время фактического возврата"
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Модуль DB-моделей ролей"""
|
||||
|
||||
from typing import TYPE_CHECKING, List
|
||||
|
||||
from sqlmodel import Field, Relationship
|
||||
@@ -12,8 +13,11 @@ if TYPE_CHECKING:
|
||||
|
||||
class Role(RoleBase, table=True):
|
||||
"""Модель роли в базе данных"""
|
||||
|
||||
__tablename__ = "roles"
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True, index=True)
|
||||
id: int | None = Field(
|
||||
default=None, primary_key=True, index=True, description="Идентификатор"
|
||||
)
|
||||
|
||||
users: List["User"] = Relationship(back_populates="roles", link_model=UserRoleLink)
|
||||
|
||||
@@ -17,17 +17,32 @@ class User(UserBase, table=True):
|
||||
|
||||
__tablename__ = "users"
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True, index=True)
|
||||
hashed_password: str = Field(nullable=False)
|
||||
is_2fa_enabled: bool = Field(default=False)
|
||||
totp_secret: str | None = Field(default=None, max_length=80)
|
||||
recovery_code_hashes: str | None = Field(default=None, max_length=1500)
|
||||
recovery_codes_generated_at: datetime | None = Field(default=None)
|
||||
is_active: bool = Field(default=True)
|
||||
is_verified: bool = Field(default=False)
|
||||
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
||||
id: int | None = Field(
|
||||
default=None, primary_key=True, index=True, description="Идентификатор"
|
||||
)
|
||||
hashed_password: str = Field(nullable=False, description="Argon2id хэш пароля")
|
||||
is_2fa_enabled: bool = Field(default=False, description="Включен TOTP 2FA")
|
||||
totp_secret: str | None = Field(
|
||||
default=None, max_length=80, description="Зашифрованный секрет TOTP"
|
||||
)
|
||||
recovery_code_hashes: str | None = Field(
|
||||
default=None,
|
||||
max_length=1500,
|
||||
description="Argon2id хэши одноразовыхкодов восстановления",
|
||||
)
|
||||
recovery_codes_generated_at: datetime | None = Field(
|
||||
default=None, description="Дата и время создания кодов восстановления"
|
||||
)
|
||||
is_active: bool = Field(default=True, description="Не является ли заблокированым")
|
||||
is_verified: bool = Field(default=False, description="Является ли верифицированным")
|
||||
created_at: datetime = Field(
|
||||
default_factory=lambda: datetime.now(timezone.utc),
|
||||
description="Дата и время создания",
|
||||
)
|
||||
updated_at: datetime | None = Field(
|
||||
default=None, sa_column_kwargs={"onupdate": lambda: datetime.now(timezone.utc)}
|
||||
default=None,
|
||||
sa_column_kwargs={"onupdate": lambda: datetime.now(timezone.utc)},
|
||||
description="Дата и время последнего обновления",
|
||||
)
|
||||
|
||||
roles: List["Role"] = Relationship(back_populates="users", link_model=UserRoleLink)
|
||||
|
||||
Reference in New Issue
Block a user