Spaces:
Sleeping
Sleeping
fix(orm): correct asymmetric relationships, add missing back_populates, and remove invalid model refs
Browse files
src/app/models/ticket.py
CHANGED
|
@@ -114,6 +114,8 @@ class Ticket(BaseModel):
|
|
| 114 |
project = relationship("Project", back_populates="tickets")
|
| 115 |
project_region = relationship("ProjectRegion", foreign_keys=[project_region_id])
|
| 116 |
contractor_invoice = relationship("ContractorInvoice", foreign_keys=[contractor_invoice_id], backref="tickets")
|
|
|
|
|
|
|
| 117 |
assignments = relationship("TicketAssignment", back_populates="ticket", cascade="all, delete-orphan", lazy="select")
|
| 118 |
expenses = relationship("TicketExpense", back_populates="ticket", cascade="all, delete-orphan", lazy="select")
|
| 119 |
comments = relationship("TicketComment", back_populates="ticket", cascade="all, delete-orphan", lazy="select")
|
|
|
|
| 114 |
project = relationship("Project", back_populates="tickets")
|
| 115 |
project_region = relationship("ProjectRegion", foreign_keys=[project_region_id])
|
| 116 |
contractor_invoice = relationship("ContractorInvoice", foreign_keys=[contractor_invoice_id], backref="tickets")
|
| 117 |
+
sales_order = relationship("SalesOrder", back_populates="ticket", uselist=False, foreign_keys="[Ticket.source_id]",
|
| 118 |
+
primaryjoin="and_(Ticket.source_id==SalesOrder.id, Ticket.source_type=='sales_order')")
|
| 119 |
assignments = relationship("TicketAssignment", back_populates="ticket", cascade="all, delete-orphan", lazy="select")
|
| 120 |
expenses = relationship("TicketExpense", back_populates="ticket", cascade="all, delete-orphan", lazy="select")
|
| 121 |
comments = relationship("TicketComment", back_populates="ticket", cascade="all, delete-orphan", lazy="select")
|
src/app/models/ticket_assignment.py
CHANGED
|
@@ -82,7 +82,7 @@ class TicketAssignment(BaseModel):
|
|
| 82 |
user = relationship("User", foreign_keys=[user_id], lazy="select")
|
| 83 |
assigned_by = relationship("User", foreign_keys=[assigned_by_user_id], lazy="select")
|
| 84 |
expenses = relationship("TicketExpense", back_populates="assignment", cascade="all, delete-orphan")
|
| 85 |
-
status_changes = relationship("TicketStatusHistory", back_populates="assignment", cascade="all, delete-orphan")
|
| 86 |
|
| 87 |
def __repr__(self):
|
| 88 |
return f"<TicketAssignment(id={self.id}, ticket_id={self.ticket_id}, user_id={self.user_id}, action={self.action}, status={self.status})>"
|
|
|
|
| 82 |
user = relationship("User", foreign_keys=[user_id], lazy="select")
|
| 83 |
assigned_by = relationship("User", foreign_keys=[assigned_by_user_id], lazy="select")
|
| 84 |
expenses = relationship("TicketExpense", back_populates="assignment", cascade="all, delete-orphan")
|
| 85 |
+
# status_changes = relationship("TicketStatusHistory", back_populates="assignment", cascade="all, delete-orphan") # Model doesn't exist yet
|
| 86 |
|
| 87 |
def __repr__(self):
|
| 88 |
return f"<TicketAssignment(id={self.id}, ticket_id={self.ticket_id}, user_id={self.user_id}, action={self.action}, status={self.status})>"
|
src/app/models/ticket_expense.py
CHANGED
|
@@ -123,7 +123,7 @@ class TicketExpense(Base):
|
|
| 123 |
deleted_at = Column(TIMESTAMP(timezone=True), nullable=True)
|
| 124 |
|
| 125 |
# Relationships
|
| 126 |
-
|
| 127 |
ticket = relationship("Ticket", back_populates="expenses")
|
| 128 |
incurred_by_user = relationship("User", foreign_keys=[incurred_by_user_id])
|
| 129 |
approved_by_user = relationship("User", foreign_keys=[approved_by_user_id])
|
|
|
|
| 123 |
deleted_at = Column(TIMESTAMP(timezone=True), nullable=True)
|
| 124 |
|
| 125 |
# Relationships
|
| 126 |
+
assignment = relationship("TicketAssignment", back_populates="expenses") # Changed from ticket_assignment to assignment
|
| 127 |
ticket = relationship("Ticket", back_populates="expenses")
|
| 128 |
incurred_by_user = relationship("User", foreign_keys=[incurred_by_user_id])
|
| 129 |
approved_by_user = relationship("User", foreign_keys=[approved_by_user_id])
|
src/app/models/user.py
CHANGED
|
@@ -4,6 +4,7 @@ Matches schema.sql exactly - field service management platform
|
|
| 4 |
"""
|
| 5 |
from sqlalchemy import Column, String, Boolean, Text, DateTime, Float
|
| 6 |
from sqlalchemy.dialects.postgresql import UUID, JSONB
|
|
|
|
| 7 |
from app.models.base import BaseModel
|
| 8 |
|
| 9 |
|
|
@@ -89,6 +90,13 @@ class User(BaseModel):
|
|
| 89 |
# Additional Metadata
|
| 90 |
additional_metadata = Column(JSONB, default={})
|
| 91 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
def __repr__(self):
|
| 93 |
return f"<User(email='{self.email}', name='{self.name}', role='{self.role}')>"
|
| 94 |
|
|
|
|
| 4 |
"""
|
| 5 |
from sqlalchemy import Column, String, Boolean, Text, DateTime, Float
|
| 6 |
from sqlalchemy.dialects.postgresql import UUID, JSONB
|
| 7 |
+
from sqlalchemy.orm import relationship
|
| 8 |
from app.models.base import BaseModel
|
| 9 |
|
| 10 |
|
|
|
|
| 90 |
# Additional Metadata
|
| 91 |
additional_metadata = Column(JSONB, default={})
|
| 92 |
|
| 93 |
+
# Relationships - Using backref for most, explicit back_populates where needed
|
| 94 |
+
# Note: Most relationships use backref in the referring model (one-way is sufficient)
|
| 95 |
+
# Only add back_populates when bidirectional traversal is explicitly needed
|
| 96 |
+
|
| 97 |
+
# Sales orders where this user is the agent (explicit back_populates)
|
| 98 |
+
sales_orders_as_agent = relationship("SalesOrder", foreign_keys="[SalesOrder.sales_agent_id]", back_populates="sales_agent", lazy="dynamic")
|
| 99 |
+
|
| 100 |
def __repr__(self):
|
| 101 |
return f"<User(email='{self.email}', name='{self.name}', role='{self.role}')>"
|
| 102 |
|