ports.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. """存储后端抽象接口 (Ports) —— 定义所有存储引擎的统一契约
  2. Domain 层只依赖这里的抽象,Infra 层提供具体实现。
  3. """
  4. import logging
  5. from abc import ABC, abstractmethod
  6. from enum import Enum
  7. from typing import Any, Optional
  8. logger = logging.getLogger(__name__)
  9. class BackendType(str, Enum):
  10. """存储后端类型枚举"""
  11. MYSQL = "mysql"
  12. POSTGRESQL = "postgresql"
  13. MILVUS = "milvus"
  14. REDIS = "redis"
  15. class BaseBackend(ABC):
  16. """所有存储后端的抽象基类"""
  17. def __init__(self, name: str, config: Any):
  18. self.name = name
  19. self.config = config
  20. self._initialized = False
  21. @abstractmethod
  22. async def init(self) -> None:
  23. """初始化连接池或客户端,失败抛异常"""
  24. ...
  25. @abstractmethod
  26. async def close(self) -> None:
  27. """关闭连接池或客户端,安全可幂等"""
  28. ...
  29. @abstractmethod
  30. async def health(self) -> bool:
  31. """健康检查:ping 成功后返回 True"""
  32. ...
  33. @property
  34. def initialized(self) -> bool:
  35. return self._initialized
  36. class SqlBackend(BaseBackend):
  37. """SQL 类后端的公共抽象(MySQL / PostgreSQL)"""
  38. @abstractmethod
  39. async def fetch(
  40. self,
  41. query: str,
  42. params: Optional[tuple] = None,
  43. ) -> list[dict]:
  44. """SELECT 多行"""
  45. ...
  46. @abstractmethod
  47. async def fetch_one(
  48. self,
  49. query: str,
  50. params: Optional[tuple] = None,
  51. ) -> Optional[dict]:
  52. """SELECT 单行"""
  53. ...
  54. @abstractmethod
  55. async def execute(
  56. self,
  57. query: str,
  58. params: Any = None,
  59. *,
  60. batch: bool = False,
  61. ) -> int:
  62. """INSERT/UPDATE/DELETE,返回受影响行数"""
  63. ...
  64. class VectorBackend(BaseBackend):
  65. """向量数据库的公共抽象(Milvus 等)"""
  66. @abstractmethod
  67. async def insert(
  68. self,
  69. collection: str,
  70. vectors: list[list[float]],
  71. metadata: Optional[list[dict]] = None,
  72. ) -> list[int]:
  73. """插入向量,返回主键 ID 列表"""
  74. ...
  75. @abstractmethod
  76. async def search(
  77. self,
  78. collection: str,
  79. query_vectors: list[list[float]],
  80. top_k: int = 10,
  81. filter_expr: Optional[str] = None,
  82. ) -> list[list[dict]]:
  83. """向量相似搜索"""
  84. ...
  85. @abstractmethod
  86. async def delete(
  87. self,
  88. collection: str,
  89. ids: list[int],
  90. ) -> int:
  91. """按主键删除向量"""
  92. ...
  93. class KvBackend(BaseBackend):
  94. """KV 存储的公共抽象(Redis 等)"""
  95. @abstractmethod
  96. async def get(self, key: str) -> Optional[str]:
  97. """获取键值"""
  98. ...
  99. @abstractmethod
  100. async def set(
  101. self,
  102. key: str,
  103. value: str,
  104. ttl: Optional[int] = None,
  105. ) -> bool:
  106. """写入键值,可选 TTL(秒)"""
  107. ...
  108. @abstractmethod
  109. async def delete(self, *keys: str) -> int:
  110. """删除键,返回已删除数量"""
  111. ...
  112. @abstractmethod
  113. async def exists(self, *keys: str) -> int:
  114. """检查键是否存在,返回存在的数量"""
  115. ...