diff --git a/inventory/models/__init__.py b/inventory/models/__init__.py index c1ae94b..cc57a87 100644 --- a/inventory/models/__init__.py +++ b/inventory/models/__init__.py @@ -1,30 +1,54 @@ -from typing import TYPE_CHECKING +# inventory/models/__init__.py +from inventory import db # your single SQLAlchemy() instance -from inventory import db # Yes, this works when run from project root with Alembic +# Import *modules* so all model classes are defined & registered +from . import image +from . import room_functions +from . import rooms +from . import areas +from . import brands +from . import items +from . import inventory +from . import work_log +from . import work_note +from . import users +from . import image_links -from .areas import Area -from .brands import Brand -from .items import Item -from .inventory import Inventory -from .room_functions import RoomFunction -from .users import User -from .work_log import WorkLog -from .rooms import Room -from .work_note import WorkNote -from .image import Image -from .image_links import worklog_images +# If you want convenient symbols, export them AFTER modules are imported +Image = image.Image +ImageAttachable = image.ImageAttachable +RoomFunction = room_functions.RoomFunction +Room = rooms.Room +Area = areas.Area +Brand = brands.Brand +Item = items.Item +Inventory = inventory.Inventory +WorkLog = work_log.WorkLog +WorkNote = work_note.WorkNote +worklog_images = image_links.worklog_images +User = users.User + +# Now it’s safe to configure mappers and set global eagerloads +from sqlalchemy.orm import configure_mappers, joinedload, selectinload +configure_mappers() + +User.ui_eagerload = ( + joinedload(User.supervisor), + joinedload(User.location).joinedload(Room.room_function), +) + +Room.ui_eagerload = ( + joinedload(Room.area), + joinedload(Room.room_function), + selectinload(Room.inventory), + selectinload(Room.users) +) __all__ = [ "db", - "Area", - "Brand", - "Item", - "Inventory", - "RoomFunction", + "Image", "ImageAttachable", + "RoomFunction", "Room", + "Area", "Brand", "Item", "Inventory", + "WorkLog", "WorkNote", "worklog_images", "User", - "WorkLog", - "Room", - "WorkNote", - "Image", - "worklog_images" ] diff --git a/inventory/models/rooms.py b/inventory/models/rooms.py index cd9b7b2..0244a48 100644 --- a/inventory/models/rooms.py +++ b/inventory/models/rooms.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from .users import User from sqlalchemy import ForeignKey, Identity, Integer, Unicode -from sqlalchemy.orm import Mapped, mapped_column, relationship, joinedload, selectinload +from sqlalchemy.orm import Mapped, mapped_column, relationship from . import db @@ -52,10 +52,3 @@ class Room(db.Model): name = self.name or "" func = self.room_function.description if self.room_function else "" return f"{name} - {func}".strip(" -") - -Room.ui_eagerload = ( - joinedload(Room.area), - joinedload(Room.room_function), - selectinload(Room.inventory), - selectinload(Room.users) -) \ No newline at end of file diff --git a/inventory/models/users.py b/inventory/models/users.py index 31ed34b..d1dbe9b 100644 --- a/inventory/models/users.py +++ b/inventory/models/users.py @@ -31,6 +31,8 @@ class User(db.Model, ImageAttachable): inventory: Mapped[List['Inventory']] = relationship('Inventory', back_populates='owner') image: Mapped[Optional['Image']] = relationship('Image', back_populates='user', passive_deletes=True) + ui_eagerload = tuple() + @property def identifier(self) -> str: return f"{self.first_name or ''} {self.last_name or ''}{', ' + (''.join(word[0].upper() for word in self.title.split())) if self.title else ''}".strip() @@ -73,4 +75,4 @@ class User(db.Model, ImageAttachable): title=data.get("title"), location_id=data.get("location_id"), supervisor_id=data.get("supervisor_id") - ) \ No newline at end of file + )