From 48697e44b1cccea27108f16cc211125898c3bc7f Mon Sep 17 00:00:00 2001 From: Kiveiru3 <2350059956@qq.com> Date: Sat, 5 Sep 2026 16:17:50 +0800 Subject: [PATCH] refactor(models): remove legacy db.session properties from Conversation --- api/models/model.py | 40 ------------------- .../models/test_conversation_status_count.py | 18 ++++----- .../unit_tests/models/test_app_models.py | 9 +++-- 3 files changed, 14 insertions(+), 53 deletions(-) diff --git a/api/models/model.py b/api/models/model.py index bc33dbadfb675b..60c1171f77ca9f 100644 --- a/api/models/model.py +++ b/api/models/model.py @@ -1333,10 +1333,6 @@ def model_config_with_session(self, *, session: Session) -> AppModelConfigDict: return model_config - @property - def summary_or_query(self): - return self.summary_or_query_with_session(session=db.session()) - def summary_or_query_with_session(self, *, session: Session) -> str: if self.summary: return self.summary @@ -1347,41 +1343,21 @@ def summary_or_query_with_session(self, *, session: Session) -> str: else: return "" - @property - def annotated(self) -> bool: - return self.annotated_with_session(session=db.session()) - def annotated_with_session(self, *, session: Session) -> bool: return ( session.scalar(select(func.count(MessageAnnotation.id)).where(MessageAnnotation.conversation_id == self.id)) or 0 ) > 0 - @property - def annotation(self) -> MessageAnnotation | None: - return self.annotation_with_session(session=db.session()) - def annotation_with_session(self, *, session: Session) -> MessageAnnotation | None: return session.scalar(select(MessageAnnotation).where(MessageAnnotation.conversation_id == self.id).limit(1)) - @property - def message_count(self) -> int: - return self.message_count_with_session(session=db.session()) - def message_count_with_session(self, *, session: Session) -> int: return session.scalar(select(func.count(Message.id)).where(Message.conversation_id == self.id)) or 0 - @property - def user_feedback_stats(self) -> dict[str, int]: - return self.user_feedback_stats_with_session(session=db.session()) - def user_feedback_stats_with_session(self, *, session: Session) -> dict[str, int]: return self._feedback_stats_with_session(session=session, from_source=FeedbackFromSource.USER) - @property - def admin_feedback_stats(self) -> dict[str, int]: - return self.admin_feedback_stats_with_session(session=db.session()) - def admin_feedback_stats_with_session(self, *, session: Session) -> dict[str, int]: return self._feedback_stats_with_session(session=session, from_source=FeedbackFromSource.ADMIN) @@ -1410,10 +1386,6 @@ def _feedback_stats_with_session(self, *, session: Session, from_source: Feedbac return {"like": like, "dislike": dislike} - @property - def status_count(self): - return self.status_count_with_session(session=db.session()) - def status_count_with_session(self, *, session: Session) -> dict[str, int] | None: from models.workflow import WorkflowRun @@ -1468,10 +1440,6 @@ def status_count_with_session(self, *, session: Session) -> dict[str, int] | Non "paused": status_counts[WorkflowExecutionStatus.PAUSED], } - @property - def first_message(self) -> Message | None: - return self.first_message_with_session(session=db.session()) - def first_message_with_session(self, *, session: Session) -> Message | None: return session.scalar( select(Message).where(Message.conversation_id == self.id).order_by(Message.created_at.asc()) @@ -1482,10 +1450,6 @@ def app(self) -> App | None: with Session(db.engine, expire_on_commit=False) as session: return session.scalar(select(App).where(App.id == self.app_id)) - @property - def from_end_user_session_id(self) -> str | None: - return self.from_end_user_session_id_with_session(session=db.session()) - def from_end_user_session_id_with_session(self, *, session: Session) -> str | None: if self.from_end_user_id: end_user = session.scalar(select(EndUser).where(EndUser.id == self.from_end_user_id)) @@ -1494,10 +1458,6 @@ def from_end_user_session_id_with_session(self, *, session: Session) -> str | No return None - @property - def from_account_name(self) -> str | None: - return self.from_account_name_with_session(session=db.session()) - def from_account_name_with_session(self, *, session: Session) -> str | None: if self.from_account_id: account = session.scalar(select(Account).where(Account.id == self.from_account_id)) diff --git a/api/tests/test_containers_integration_tests/models/test_conversation_status_count.py b/api/tests/test_containers_integration_tests/models/test_conversation_status_count.py index 9ad43df5402aab..96d672d5e4eaac 100644 --- a/api/tests/test_containers_integration_tests/models/test_conversation_status_count.py +++ b/api/tests/test_containers_integration_tests/models/test_conversation_status_count.py @@ -1,5 +1,5 @@ """ -Integration tests for Conversation.status_count and Site.generate_code model properties. +Integration tests for Conversation.status_count_with_session and Site.generate_code. Migrated from unit_tests/models/test_app_models.py TestConversationStatusCount and test_site_generate_code, replacing db.session.scalars mocks with real PostgreSQL queries. @@ -18,7 +18,7 @@ class TestConversationStatusCount: - """Integration tests for Conversation.status_count property.""" + """Integration tests for Conversation.status_count_with_session.""" @pytest.fixture(autouse=True) def _auto_rollback(self, db_session_with_containers: Session) -> Generator[None, None, None]: @@ -130,7 +130,7 @@ def test_status_count_returns_none_when_no_messages(self, db_session_with_contai app = self._create_app(db_session_with_containers, tenant_id, created_by) conversation = self._create_conversation(db_session_with_containers, app) - result = conversation.status_count + result = conversation.status_count_with_session(session=db_session_with_containers) assert result is None @@ -145,7 +145,7 @@ def test_status_count_returns_none_when_messages_have_no_workflow_run_id( conversation = self._create_conversation(db_session_with_containers, app) self._create_message(db_session_with_containers, app, conversation, workflow_run_id=None) - result = conversation.status_count + result = conversation.status_count_with_session(session=db_session_with_containers) assert result is None @@ -162,7 +162,7 @@ def test_status_count_counts_succeeded_workflow_run(self, db_session_with_contai ) self._create_message(db_session_with_containers, app, conversation, workflow_run_id=run.id) - result = conversation.status_count + result = conversation.status_count_with_session(session=db_session_with_containers) assert result is not None assert result["success"] == 1 @@ -183,7 +183,7 @@ def test_status_count_counts_failed_workflow_run(self, db_session_with_container ) self._create_message(db_session_with_containers, app, conversation, workflow_run_id=run.id) - result = conversation.status_count + result = conversation.status_count_with_session(session=db_session_with_containers) assert result is not None assert result["success"] == 0 @@ -204,7 +204,7 @@ def test_status_count_counts_paused_workflow_run(self, db_session_with_container ) self._create_message(db_session_with_containers, app, conversation, workflow_run_id=run.id) - result = conversation.status_count + result = conversation.status_count_with_session(session=db_session_with_containers) assert result is not None assert result["success"] == 0 @@ -230,7 +230,7 @@ def test_status_count_multiple_statuses(self, db_session_with_containers: Sessio run = self._create_workflow_run(db_session_with_containers, app, workflow, status, created_by) self._create_message(db_session_with_containers, app, conversation, workflow_run_id=run.id) - result = conversation.status_count + result = conversation.status_count_with_session(session=db_session_with_containers) assert result is not None assert result["success"] == 1 @@ -255,7 +255,7 @@ def test_status_count_filters_workflow_runs_by_app_id(self, db_session_with_cont # Message references that run but is in a conversation under app self._create_message(db_session_with_containers, app, conversation, workflow_run_id=other_run.id) - result = conversation.status_count + result = conversation.status_count_with_session(session=db_session_with_containers) # The run should be excluded because app_id filter doesn't match assert result is not None diff --git a/api/tests/unit_tests/models/test_app_models.py b/api/tests/unit_tests/models/test_app_models.py index d00060312ad363..7c7e2a8163d6f2 100644 --- a/api/tests/unit_tests/models/test_app_models.py +++ b/api/tests/unit_tests/models/test_app_models.py @@ -541,8 +541,9 @@ def test_conversation_inputs_setter(self): # Assert assert conversation._inputs == inputs - def test_conversation_summary_or_query_with_summary(self): - """Test summary_or_query property when summary exists.""" + @pytest.mark.parametrize("sqlite_session", [(Conversation, Message)], indirect=True) + def test_conversation_summary_or_query_with_summary(self, sqlite_session: Session): + """Test summary_or_query_with_session when summary exists.""" # Arrange conversation = Conversation( app_id=str(uuid4()), @@ -555,14 +556,14 @@ def test_conversation_summary_or_query_with_summary(self): ) # Act - result = conversation.summary_or_query + result = conversation.summary_or_query_with_session(session=sqlite_session) # Assert assert result == "Test summary" @pytest.mark.parametrize("sqlite_session", [(Conversation, Message)], indirect=True) def test_conversation_summary_or_query_without_summary(self, sqlite_session: Session): - """Test summary_or_query property when summary is empty.""" + """Test summary_or_query_with_session when summary is empty.""" # Arrange conversation = Conversation( app_id=str(uuid4()),