Compare commits

...

15 Commits

Author SHA1 Message Date
-LAN-
cdca0d3789 Remove is_deleted from conversation test 2026-01-28 01:25:11 +08:00
-LAN-
29ce6fd2cd chore: upgrade migrations
Signed-off-by: -LAN- <laipz8200@outlook.com>
2026-01-28 01:25:11 +08:00
-LAN-
476cab18df Fix migration base revision 2026-01-28 01:25:00 +08:00
-LAN-
c7fbc44257 Delete soft-deleted conversations before dropping is_deleted column
Use sa.table() with sa.delete() and sa.true() to generate cross-database
compatible SQL that works in both online and offline modes without
requiring schema reflection.
2026-01-28 01:23:02 +08:00
-LAN-
a15f80dda3 Simplify is_deleted migration: drop column without backup 2026-01-28 01:23:02 +08:00
-LAN-
5858545abe Drop offline guards in is_deleted migration 2026-01-28 01:23:02 +08:00
-LAN-
7193bdec8c Use SQLAlchemy expressions for is_deleted migration backup 2026-01-28 01:23:01 +08:00
-LAN-
3b24678d2a Handle offline migrations and MySQL/PostgreSQL booleans 2026-01-28 01:23:01 +08:00
-LAN-
231581f67e Make conversation is_deleted migration cross-database safe 2026-01-28 01:23:01 +08:00
-LAN-
5e9f4bface Fix migration down_revision after merge 2026-01-28 01:23:01 +08:00
-LAN-
2707db383f refactor: use SQLAlchemy inspector for database-agnostic table existence check
Replace PostgreSQL-specific information_schema query with SQLAlchemy's
inspector API that works across all supported database types.
2026-01-28 01:23:01 +08:00
-LAN-
c35ecf77ca refactor: extract backup table name as module constant
Share backup_table_name between upgrade() and downgrade() functions
to avoid duplication and ensure consistency.
2026-01-28 01:23:01 +08:00
-LAN-
e1777d0f09 refactor: backup soft-deleted conversations instead of deleting them
- Create backup table conversations_4f02b6704509_bak for soft-deleted records
- Only create backup table if soft-deleted records exist
- Support recovery during downgrade migration
- Drop backup table after successful restoration
2026-01-28 01:23:01 +08:00
-LAN-
979dec1dbc fix: delete soft-deleted conversations before dropping is_deleted column
Ensure any existing soft-deleted conversations are removed from the
database before dropping the is_deleted column in the migration.
2026-01-28 01:23:00 +08:00
-LAN-
74202586da refactor: remove unused is_deleted field from conversations table
Remove the is_deleted field that was never utilized for soft deletion.
This simplifies queries and reduces unnecessary database overhead.

Fixes #25017
2026-01-28 01:23:00 +08:00
6 changed files with 38 additions and 10 deletions

View File

@@ -343,9 +343,7 @@ class CompletionConversationApi(Resource):
current_user, _ = current_account_with_tenant()
args = CompletionConversationQuery.model_validate(request.args.to_dict(flat=True)) # type: ignore
query = sa.select(Conversation).where(
Conversation.app_id == app_model.id, Conversation.mode == "completion", Conversation.is_deleted.is_(False)
)
query = sa.select(Conversation).where(Conversation.app_id == app_model.id, Conversation.mode == "completion")
if args.keyword:
from libs.helper import escape_like_pattern
@@ -460,7 +458,7 @@ class ChatConversationApi(Resource):
.subquery()
)
query = sa.select(Conversation).where(Conversation.app_id == app_model.id, Conversation.is_deleted.is_(False))
query = sa.select(Conversation).where(Conversation.app_id == app_model.id)
if args.keyword:
from libs.helper import escape_like_pattern

View File

@@ -0,0 +1,36 @@
"""remove unused is_deleted from conversations
Revision ID: e5d7a95e676f
Revises: 288345cd01d1
Create Date: 2025-11-27 18:27:09.006691
"""
import sqlalchemy as sa
from alembic import op
revision = "e5d7a95e676f"
down_revision = "9d77545f524e"
branch_labels = None
depends_on = None
def upgrade():
conversations = sa.table("conversations", sa.column("is_deleted", sa.Boolean))
op.execute(sa.delete(conversations).where(conversations.c.is_deleted == sa.true()))
with op.batch_alter_table("conversations", schema=None) as batch_op:
batch_op.drop_column("is_deleted")
def downgrade():
with op.batch_alter_table("conversations", schema=None) as batch_op:
batch_op.add_column(
sa.Column(
"is_deleted",
sa.BOOLEAN(),
server_default=sa.text("false"),
autoincrement=False,
nullable=False,
)
)

View File

@@ -745,8 +745,6 @@ class Conversation(Base):
"MessageAnnotation", backref="conversation", lazy="select", passive_deletes="all"
)
is_deleted: Mapped[bool] = mapped_column(sa.Boolean, nullable=False, server_default=sa.text("false"))
@property
def inputs(self) -> dict[str, Any]:
inputs = self._inputs.copy()

View File

@@ -49,7 +49,6 @@ class ConversationService:
return InfiniteScrollPagination(data=[], limit=limit, has_more=False)
stmt = select(Conversation).where(
Conversation.is_deleted == False,
Conversation.app_id == app_model.id,
Conversation.from_source == ("api" if isinstance(user, EndUser) else "console"),
Conversation.from_end_user_id == (user.id if isinstance(user, EndUser) else None),
@@ -168,7 +167,6 @@ class ConversationService:
Conversation.from_source == ("api" if isinstance(user, EndUser) else "console"),
Conversation.from_end_user_id == (user.id if isinstance(user, EndUser) else None),
Conversation.from_account_id == (user.id if isinstance(user, Account) else None),
Conversation.is_deleted == False,
)
.first()
)

View File

@@ -149,7 +149,6 @@ class TestWebConversationService:
from_end_user_id=user.id if isinstance(user, EndUser) else None,
from_account_id=user.id if isinstance(user, Account) else None,
dialogue_count=0,
is_deleted=False,
)
from extensions.ext_database import db

View File

@@ -184,7 +184,6 @@ class ConversationServiceTestDataFactory:
conversation.from_source = from_source
conversation.from_end_user_id = kwargs.get("from_end_user_id")
conversation.from_account_id = kwargs.get("from_account_id")
conversation.is_deleted = kwargs.get("is_deleted", False)
conversation.name = kwargs.get("name", "Test Conversation")
conversation.status = kwargs.get("status", "normal")
conversation.created_at = kwargs.get("created_at", datetime.now(UTC))