From d86240e47efc9d717e2f574072588fc0fdb03e20 Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Sun, 7 Sep 2025 16:12:53 -0600 Subject: [PATCH 1/7] refactor: update model syntax to conform to the latest type-hinting/mapping styles for SQL Alchemy 2.0 --- db/location.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/db/location.py b/db/location.py index eb477d93f..5c83c3766 100644 --- a/db/location.py +++ b/db/location.py @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # =============================================================================== +import datetime + from geoalchemy2 import Geometry, WKBElement from geoalchemy2.shape import to_shape @@ -36,15 +38,15 @@ class Location(Base, AutoBaseMixin, ReleaseMixin): # visible = Column(Boolean, default=False, nullable=False) __versioned__ = {} - name = mapped_column(String(255), nullable=True) - notes = mapped_column(Text, nullable=True) + name: Mapped[str] = mapped_column(String(255), nullable=True) + notes: Mapped[str] = mapped_column(Text, nullable=True) point: Mapped[WKBElement] = mapped_column( Geometry(geometry_type="POINTZ", srid=4326, spatial_index=True) ) - state = lexicon_term(nullable=True) - county = lexicon_term(nullable=True) - quad_name = mapped_column(String(100), nullable=True) + state: Mapped[str] = lexicon_term(nullable=True, default = "New Mexico") + county: Mapped[str] = lexicon_term(nullable=True) + quad_name: Mapped[str] = mapped_column(String(100), nullable=True) @property def latlon(self): @@ -53,20 +55,25 @@ def latlon(self): class LocationThingAssociation(Base, AutoBaseMixin): - location_id = Column( - Integer, ForeignKey("location.id", ondelete="CASCADE"), primary_key=True + location_id: Mapped[int] = mapped_column( + ForeignKey("location.id", ondelete="CASCADE"), + primary_key=True ) - thing_id = Column( - Integer, ForeignKey("thing.id", ondelete="CASCADE"), primary_key=True + thing_id: Mapped[int] = mapped_column( + ForeignKey("thing.id", ondelete="CASCADE"), + primary_key=True ) # REFACTOR TODO: when refactoring/updating location/thing schemas and tests, ensure timezone is UTC - effective_start = Column( + effective_start: Mapped[datetime.datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.timezone("UTC", func.now()), ) - effective_end = Column(DateTime(timezone=True), nullable=True) + effective_end: Mapped[datetime.datetime] = mapped_column( + DateTime(timezone=True), + nullable=True + ) location = relationship("Location") thing = relationship("Thing") From 6425e656d4a6a6e93a7fdb6d09eb29a6699030ed Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Sun, 7 Sep 2025 22:19:56 -0600 Subject: [PATCH 2/7] refactor: update relationships in the LocationThingAssociation model to reflect the use of proxies --- db/location.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/db/location.py b/db/location.py index 5c83c3766..3241de0da 100644 --- a/db/location.py +++ b/db/location.py @@ -28,6 +28,7 @@ Text, ) from sqlalchemy.orm import relationship, Mapped, mapped_column +from sqlalchemy.ext.associationproxy import association_proxy, AssociationProxy from db.base import Base, AutoBaseMixin, ReleaseMixin from db.lexicon import lexicon_term @@ -48,6 +49,15 @@ class Location(Base, AutoBaseMixin, ReleaseMixin): county: Mapped[str] = lexicon_term(nullable=True) quad_name: Mapped[str] = mapped_column(String(100), nullable=True) + # --- Relationship Definitions --- + thing_associations: Mapped[list["LocationThingAssociation"]] = relationship( + back_populates="location", + cascade="all, delete-orphan" + ) + + # --- Proxy Definitions --- + things: AssociationProxy[list["Thing"]] = association_proxy("thing_associations", "thing") + @property def latlon(self): p = to_shape(self.point) @@ -75,8 +85,9 @@ class LocationThingAssociation(Base, AutoBaseMixin): nullable=True ) - location = relationship("Location") - thing = relationship("Thing") + # --- Relationship Definitions --- + location: Mapped["Location"] = relationship(back_populates= "thing_associations") + thing: Mapped["Thing"] = relationship(back_populates = "location_associations") # ============= EOF ============================================= From c5df34f0e8fc2335572505a46ce920e064242409 Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Sun, 7 Sep 2025 22:33:02 -0600 Subject: [PATCH 3/7] feat: add new fields and relationship to Location model --- db/location.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/db/location.py b/db/location.py index 3241de0da..2a3f1fceb 100644 --- a/db/location.py +++ b/db/location.py @@ -39,8 +39,9 @@ class Location(Base, AutoBaseMixin, ReleaseMixin): # visible = Column(Boolean, default=False, nullable=False) __versioned__ = {} + nma_pk_location: Mapped[UUID] = mapped_column(String(36), nullable=True, unique=True) + description: Mapped[str] = mapped_column name: Mapped[str] = mapped_column(String(255), nullable=True) - notes: Mapped[str] = mapped_column(Text, nullable=True) point: Mapped[WKBElement] = mapped_column( Geometry(geometry_type="POINTZ", srid=4326, spatial_index=True) ) @@ -48,6 +49,8 @@ class Location(Base, AutoBaseMixin, ReleaseMixin): state: Mapped[str] = lexicon_term(nullable=True, default = "New Mexico") county: Mapped[str] = lexicon_term(nullable=True) quad_name: Mapped[str] = mapped_column(String(100), nullable=True) + notes: Mapped[str] = mapped_column(Text, nullable=True) + nma_notes_location: Mapped[str] = mapped_column(Text, nullable=True) # --- Relationship Definitions --- thing_associations: Mapped[list["LocationThingAssociation"]] = relationship( From 2f47ccc419b1d2c4fe44fd197c27f4bb9b34e33f Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Mon, 8 Sep 2025 04:34:11 +0000 Subject: [PATCH 4/7] Formatting changes --- db/location.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/db/location.py b/db/location.py index 2a3f1fceb..054714151 100644 --- a/db/location.py +++ b/db/location.py @@ -39,14 +39,16 @@ class Location(Base, AutoBaseMixin, ReleaseMixin): # visible = Column(Boolean, default=False, nullable=False) __versioned__ = {} - nma_pk_location: Mapped[UUID] = mapped_column(String(36), nullable=True, unique=True) + nma_pk_location: Mapped[UUID] = mapped_column( + String(36), nullable=True, unique=True + ) description: Mapped[str] = mapped_column name: Mapped[str] = mapped_column(String(255), nullable=True) point: Mapped[WKBElement] = mapped_column( Geometry(geometry_type="POINTZ", srid=4326, spatial_index=True) ) - state: Mapped[str] = lexicon_term(nullable=True, default = "New Mexico") + state: Mapped[str] = lexicon_term(nullable=True, default="New Mexico") county: Mapped[str] = lexicon_term(nullable=True) quad_name: Mapped[str] = mapped_column(String(100), nullable=True) notes: Mapped[str] = mapped_column(Text, nullable=True) @@ -54,12 +56,13 @@ class Location(Base, AutoBaseMixin, ReleaseMixin): # --- Relationship Definitions --- thing_associations: Mapped[list["LocationThingAssociation"]] = relationship( - back_populates="location", - cascade="all, delete-orphan" + back_populates="location", cascade="all, delete-orphan" ) # --- Proxy Definitions --- - things: AssociationProxy[list["Thing"]] = association_proxy("thing_associations", "thing") + things: AssociationProxy[list["Thing"]] = association_proxy( + "thing_associations", "thing" + ) @property def latlon(self): @@ -69,12 +72,10 @@ def latlon(self): class LocationThingAssociation(Base, AutoBaseMixin): location_id: Mapped[int] = mapped_column( - ForeignKey("location.id", ondelete="CASCADE"), - primary_key=True + ForeignKey("location.id", ondelete="CASCADE"), primary_key=True ) thing_id: Mapped[int] = mapped_column( - ForeignKey("thing.id", ondelete="CASCADE"), - primary_key=True + ForeignKey("thing.id", ondelete="CASCADE"), primary_key=True ) # REFACTOR TODO: when refactoring/updating location/thing schemas and tests, ensure timezone is UTC @@ -84,13 +85,12 @@ class LocationThingAssociation(Base, AutoBaseMixin): server_default=func.timezone("UTC", func.now()), ) effective_end: Mapped[datetime.datetime] = mapped_column( - DateTime(timezone=True), - nullable=True + DateTime(timezone=True), nullable=True ) # --- Relationship Definitions --- - location: Mapped["Location"] = relationship(back_populates= "thing_associations") - thing: Mapped["Thing"] = relationship(back_populates = "location_associations") + location: Mapped["Location"] = relationship(back_populates="thing_associations") + thing: Mapped["Thing"] = relationship(back_populates="location_associations") # ============= EOF ============================================= From 217f6430e4088e4b4cbf49197cfe6680c96634c8 Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Mon, 8 Sep 2025 11:00:25 -0600 Subject: [PATCH 5/7] refactor: import UUID and reference to Thing model --- db/location.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db/location.py b/db/location.py index 054714151..2b02f6f3f 100644 --- a/db/location.py +++ b/db/location.py @@ -26,17 +26,17 @@ DateTime, func, Text, + UUID, ) from sqlalchemy.orm import relationship, Mapped, mapped_column from sqlalchemy.ext.associationproxy import association_proxy, AssociationProxy + +from db import Thing from db.base import Base, AutoBaseMixin, ReleaseMixin from db.lexicon import lexicon_term class Location(Base, AutoBaseMixin, ReleaseMixin): - # name = Column(String(100), nullable=True) - # description = Column(String(255), nullable=True) - # visible = Column(Boolean, default=False, nullable=False) __versioned__ = {} nma_pk_location: Mapped[UUID] = mapped_column( From 14babddfdf6ddb54d4408d073d25c2cbdb07a5f0 Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Mon, 8 Sep 2025 11:13:05 -0600 Subject: [PATCH 6/7] refactor: import UUID from uuid --- db/location.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/location.py b/db/location.py index 2b02f6f3f..b2d47801b 100644 --- a/db/location.py +++ b/db/location.py @@ -18,6 +18,8 @@ from geoalchemy2 import Geometry, WKBElement from geoalchemy2.shape import to_shape +from uuid import UUID + from sqlalchemy import ( Column, Integer, @@ -26,7 +28,6 @@ DateTime, func, Text, - UUID, ) from sqlalchemy.orm import relationship, Mapped, mapped_column from sqlalchemy.ext.associationproxy import association_proxy, AssociationProxy From 1914032c5c0660e3759dac08797f141079798ab5 Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Mon, 8 Sep 2025 11:16:00 -0600 Subject: [PATCH 7/7] refactor: remove import reference to db.Thing --- db/location.py | 1 - 1 file changed, 1 deletion(-) diff --git a/db/location.py b/db/location.py index b2d47801b..397fba62c 100644 --- a/db/location.py +++ b/db/location.py @@ -32,7 +32,6 @@ from sqlalchemy.orm import relationship, Mapped, mapped_column from sqlalchemy.ext.associationproxy import association_proxy, AssociationProxy -from db import Thing from db.base import Base, AutoBaseMixin, ReleaseMixin from db.lexicon import lexicon_term