diff --git a/astrbot/core/db/__init__.py b/astrbot/core/db/__init__.py index c62e49289..84b40ec18 100644 --- a/astrbot/core/db/__init__.py +++ b/astrbot/core/db/__init__.py @@ -5,8 +5,7 @@ from contextlib import asynccontextmanager from dataclasses import dataclass from deprecated import deprecated -from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine -from sqlalchemy.orm import sessionmaker +from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine from astrbot.core.db.po import ( Attachment, @@ -31,7 +30,7 @@ class BaseDatabase(abc.ABC): echo=False, future=True, ) - self.AsyncSessionLocal = sessionmaker( + self.AsyncSessionLocal = async_sessionmaker( self.engine, class_=AsyncSession, expire_on_commit=False, diff --git a/astrbot/core/db/migration/migra_3_to_4.py b/astrbot/core/db/migration/migra_3_to_4.py index a75c60a1b..66b72d5cb 100644 --- a/astrbot/core/db/migration/migra_3_to_4.py +++ b/astrbot/core/db/migration/migra_3_to_4.py @@ -70,6 +70,7 @@ async def migration_conversation_table( logger.info( f"未找到该条旧会话对应的具体数据: {conversation}, 跳过。", ) + continue if ":" not in conv.user_id: continue session = MessageSesion.from_str(session_str=conv.user_id) @@ -207,6 +208,7 @@ async def migration_webchat_data( logger.info( f"未找到该条旧会话对应的具体数据: {conversation}, 跳过。", ) + continue if ":" in conv.user_id: continue platform_id = "webchat" diff --git a/astrbot/core/db/migration/sqlite_v3.py b/astrbot/core/db/migration/sqlite_v3.py index a301028d1..b1a780d48 100644 --- a/astrbot/core/db/migration/sqlite_v3.py +++ b/astrbot/core/db/migration/sqlite_v3.py @@ -127,7 +127,7 @@ class SQLiteDatabase: conn.text_factory = str return conn - def _exec_sql(self, sql: str, params: tuple = None): + def _exec_sql(self, sql: str, params: tuple | None = None): conn = self.conn try: c = self.conn.cursor() @@ -224,9 +224,11 @@ class SQLiteDatabase: c.close() - return Stats(platform, [], []) + return Stats(platform) - def get_conversation_by_user_id(self, user_id: str, cid: str) -> Conversation: + def get_conversation_by_user_id( + self, user_id: str, cid: str + ) -> Conversation | None: try: c = self.conn.cursor() except sqlite3.ProgrammingError: @@ -258,7 +260,7 @@ class SQLiteDatabase: (user_id, cid, history, updated_at, created_at), ) - def get_conversations(self, user_id: str) -> tuple: + def get_conversations(self, user_id: str) -> list[Conversation]: try: c = self.conn.cursor() except sqlite3.ProgrammingError: diff --git a/astrbot/core/db/po.py b/astrbot/core/db/po.py index 1e7245976..76a0f2820 100644 --- a/astrbot/core/db/po.py +++ b/astrbot/core/db/po.py @@ -18,7 +18,7 @@ class PlatformStat(SQLModel, table=True): Note: In astrbot v4, we moved `platform` table to here. """ - __tablename__ = "platform_stats" + __tablename__: str = "platform_stats" id: int = Field(primary_key=True, sa_column_kwargs={"autoincrement": True}) timestamp: datetime = Field(nullable=False) @@ -37,9 +37,10 @@ class PlatformStat(SQLModel, table=True): class ConversationV2(SQLModel, table=True): - __tablename__ = "conversations" + __tablename__: str = "conversations" - inner_conversation_id: int = Field( + inner_conversation_id: int | None = Field( + default=None, primary_key=True, sa_column_kwargs={"autoincrement": True}, ) @@ -74,7 +75,7 @@ class Persona(SQLModel, table=True): It can be used to customize the behavior of LLMs. """ - __tablename__ = "personas" + __tablename__: str = "personas" id: int | None = Field( primary_key=True, @@ -104,7 +105,7 @@ class Persona(SQLModel, table=True): class Preference(SQLModel, table=True): """This class represents preferences for bots.""" - __tablename__ = "preferences" + __tablename__: str = "preferences" id: int | None = Field( default=None, @@ -140,7 +141,7 @@ class PlatformMessageHistory(SQLModel, table=True): or platform-specific messages. """ - __tablename__ = "platform_message_history" + __tablename__: str = "platform_message_history" id: int | None = Field( primary_key=True, @@ -167,7 +168,7 @@ class Attachment(SQLModel, table=True): Attachments can be images, files, or other media types. """ - __tablename__ = "attachments" + __tablename__: str = "attachments" inner_attachment_id: int | None = Field( primary_key=True, @@ -225,17 +226,17 @@ class Personality(TypedDict): 在 v4.0.0 版本及之后,推荐使用上面的 Persona 类。并且, mood_imitation_dialogs 字段已被废弃。 """ - prompt: str = "" - name: str = "" - begin_dialogs: list[str] = [] - mood_imitation_dialogs: list[str] = [] + prompt: str + name: str + begin_dialogs: list[str] + mood_imitation_dialogs: list[str] """情感模拟对话预设。在 v4.0.0 版本及之后,已被废弃。""" - tools: list[str] | None = None + tools: list[str] | None """工具列表。None 表示使用所有工具,空列表表示不使用任何工具""" # cache - _begin_dialogs_processed: list[dict] = [] - _mood_imitation_dialogs_processed: str = "" + _begin_dialogs_processed: list[dict] + _mood_imitation_dialogs_processed: str # ==== diff --git a/astrbot/core/db/vec_db/faiss_impl/embedding_storage.py b/astrbot/core/db/vec_db/faiss_impl/embedding_storage.py index 24f1c323c..564454cb1 100644 --- a/astrbot/core/db/vec_db/faiss_impl/embedding_storage.py +++ b/astrbot/core/db/vec_db/faiss_impl/embedding_storage.py @@ -90,4 +90,6 @@ class EmbeddingStorage: path (str): 保存索引的路径 """ + if self.index is None: + return faiss.write_index(self.index, self.path)