93 lines
3.7 KiB
Python
93 lines
3.7 KiB
Python
from datetime import UTC, datetime
|
|
|
|
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, LargeBinary, String, Text
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from app.db import Base
|
|
|
|
|
|
def utcnow() -> datetime:
|
|
return datetime.now(UTC)
|
|
|
|
|
|
class Box(Base):
|
|
__tablename__ = "boxes"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True, index=True)
|
|
name: Mapped[str] = mapped_column(String(100), nullable=False)
|
|
note: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
room: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
status: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
image_blob: Mapped[bytes | None] = mapped_column(LargeBinary, nullable=True)
|
|
image_mime_type: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
image_width: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
image_height: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, nullable=False)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
default=utcnow,
|
|
onupdate=utcnow,
|
|
nullable=False,
|
|
)
|
|
|
|
items: Mapped[list["Item"]] = relationship(
|
|
back_populates="box",
|
|
cascade="all, delete-orphan",
|
|
order_by="Item.id",
|
|
)
|
|
|
|
|
|
class Item(Base):
|
|
__tablename__ = "items"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True, index=True)
|
|
box_id: Mapped[int] = mapped_column(ForeignKey("boxes.id", ondelete="CASCADE"), nullable=False)
|
|
name: Mapped[str] = mapped_column(String(100), nullable=False)
|
|
note: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
quantity: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
is_container: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
|
image_blob: Mapped[bytes | None] = mapped_column(LargeBinary, nullable=True)
|
|
image_mime_type: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
image_width: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
image_height: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, nullable=False)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
default=utcnow,
|
|
onupdate=utcnow,
|
|
nullable=False,
|
|
)
|
|
|
|
box: Mapped[Box] = relationship(back_populates="items")
|
|
subitems: Mapped[list["SubItem"]] = relationship(
|
|
back_populates="parent_item",
|
|
cascade="all, delete-orphan",
|
|
order_by="SubItem.id",
|
|
)
|
|
|
|
|
|
class SubItem(Base):
|
|
__tablename__ = "subitems"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True, index=True)
|
|
parent_item_id: Mapped[int] = mapped_column(
|
|
ForeignKey("items.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
)
|
|
name: Mapped[str] = mapped_column(String(100), nullable=False)
|
|
note: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
quantity: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
image_blob: Mapped[bytes | None] = mapped_column(LargeBinary, nullable=True)
|
|
image_mime_type: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
image_width: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
image_height: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, nullable=False)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
default=utcnow,
|
|
onupdate=utcnow,
|
|
nullable=False,
|
|
)
|
|
|
|
parent_item: Mapped[Item] = relationship(back_populates="subitems")
|