/ spoolman / database / models.py
models.py
  1  """SQLAlchemy data models."""
  2  
  3  from datetime import datetime
  4  from typing import Optional
  5  
  6  from sqlalchemy import ForeignKey, Integer, String, Text
  7  from sqlalchemy.ext.asyncio import AsyncAttrs
  8  from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
  9  
 10  
 11  class Base(AsyncAttrs, DeclarativeBase):
 12      pass
 13  
 14  
 15  class Vendor(Base):
 16      __tablename__ = "vendor"
 17  
 18      id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
 19      registered: Mapped[datetime] = mapped_column()
 20      name: Mapped[str] = mapped_column(String(64))
 21      empty_spool_weight: Mapped[float | None] = mapped_column(comment="The weight of an empty spool.")
 22      comment: Mapped[str | None] = mapped_column(String(1024))
 23      filaments: Mapped[list["Filament"]] = relationship(back_populates="vendor")
 24      external_id: Mapped[str | None] = mapped_column(String(256))
 25      extra: Mapped[list["VendorField"]] = relationship(
 26          back_populates="vendor",
 27          cascade="save-update, merge, delete, delete-orphan",
 28          lazy="joined",
 29      )
 30  
 31  
 32  class Filament(Base):
 33      __tablename__ = "filament"
 34  
 35      id: Mapped[int] = mapped_column(primary_key=True, index=True)
 36      registered: Mapped[datetime] = mapped_column()
 37      name: Mapped[str | None] = mapped_column(String(64))
 38      vendor_id: Mapped[int | None] = mapped_column(ForeignKey("vendor.id"))
 39      vendor: Mapped[Optional["Vendor"]] = relationship(back_populates="filaments")
 40      spools: Mapped[list["Spool"]] = relationship(back_populates="filament")
 41      material: Mapped[str | None] = mapped_column(String(64))
 42      price: Mapped[float | None] = mapped_column()
 43      density: Mapped[float] = mapped_column()
 44      diameter: Mapped[float] = mapped_column()
 45      weight: Mapped[float | None] = mapped_column(comment="The filament weight of a full spool (net weight).")
 46      spool_weight: Mapped[float | None] = mapped_column(comment="The weight of an empty spool.")
 47      article_number: Mapped[str | None] = mapped_column(String(64))
 48      comment: Mapped[str | None] = mapped_column(String(1024))
 49      settings_extruder_temp: Mapped[int | None] = mapped_column(comment="Overridden extruder temperature.")
 50      settings_bed_temp: Mapped[int | None] = mapped_column(comment="Overridden bed temperature.")
 51      color_hex: Mapped[str | None] = mapped_column(String(8))
 52      multi_color_hexes: Mapped[str | None] = mapped_column(String(128))
 53      multi_color_direction: Mapped[str | None] = mapped_column(String(16))
 54      external_id: Mapped[str | None] = mapped_column(String(256))
 55      extra: Mapped[list["FilamentField"]] = relationship(
 56          back_populates="filament",
 57          cascade="save-update, merge, delete, delete-orphan",
 58          lazy="joined",
 59      )
 60  
 61  
 62  class Spool(Base):
 63      __tablename__ = "spool"
 64  
 65      id: Mapped[int] = mapped_column(primary_key=True, index=True)
 66      registered: Mapped[datetime] = mapped_column()
 67      first_used: Mapped[datetime | None] = mapped_column()
 68      last_used: Mapped[datetime | None] = mapped_column()
 69      price: Mapped[float | None] = mapped_column()
 70      filament_id: Mapped[int] = mapped_column(ForeignKey("filament.id"))
 71      filament: Mapped["Filament"] = relationship(back_populates="spools")
 72      initial_weight: Mapped[float | None] = mapped_column()
 73      spool_weight: Mapped[float | None] = mapped_column()
 74      used_weight: Mapped[float] = mapped_column()
 75      location: Mapped[str | None] = mapped_column(String(64))
 76      lot_nr: Mapped[str | None] = mapped_column(String(64))
 77      comment: Mapped[str | None] = mapped_column(String(1024))
 78      archived: Mapped[bool | None] = mapped_column()
 79      extra: Mapped[list["SpoolField"]] = relationship(
 80          back_populates="spool",
 81          cascade="save-update, merge, delete, delete-orphan",
 82          lazy="joined",
 83      )
 84  
 85  
 86  class Setting(Base):
 87      __tablename__ = "setting"
 88  
 89      key: Mapped[str] = mapped_column(String(64), primary_key=True, index=True)
 90      value: Mapped[str] = mapped_column(Text())
 91      last_updated: Mapped[datetime] = mapped_column()
 92  
 93  
 94  class VendorField(Base):
 95      __tablename__ = "vendor_field"
 96  
 97      vendor_id: Mapped[int] = mapped_column(ForeignKey("vendor.id"), primary_key=True, index=True)
 98      vendor: Mapped["Vendor"] = relationship(back_populates="extra")
 99      key: Mapped[str] = mapped_column(String(64), primary_key=True, index=True)
100      value: Mapped[str] = mapped_column(Text())
101  
102  
103  class FilamentField(Base):
104      __tablename__ = "filament_field"
105  
106      filament_id: Mapped[int] = mapped_column(ForeignKey("filament.id"), primary_key=True, index=True)
107      filament: Mapped["Filament"] = relationship(back_populates="extra")
108      key: Mapped[str] = mapped_column(String(64), primary_key=True, index=True)
109      value: Mapped[str] = mapped_column(Text())
110  
111  
112  class SpoolField(Base):
113      __tablename__ = "spool_field"
114  
115      spool_id: Mapped[int] = mapped_column(ForeignKey("spool.id"), primary_key=True, index=True)
116      spool: Mapped["Spool"] = relationship(back_populates="extra")
117      key: Mapped[str] = mapped_column(String(64), primary_key=True, index=True)
118      value: Mapped[str] = mapped_column(Text())