Build lightweight AI agent admin
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
数据库兼容层工具
|
||||
|
||||
提供跨数据库(PostgreSQL、MySQL、SQL Server)的 JSON 操作兼容函数
|
||||
"""
|
||||
from typing import Any, List
|
||||
|
||||
from sqlalchemy import func, literal, text
|
||||
from sqlalchemy.sql import ColumnElement
|
||||
|
||||
|
||||
def get_db_type() -> str:
|
||||
"""
|
||||
获取当前数据库类型
|
||||
|
||||
Returns:
|
||||
数据库类型: 'postgresql', 'mysql' 或 'sqlserver'
|
||||
"""
|
||||
from app.config import settings
|
||||
|
||||
return settings.DB_TYPE
|
||||
|
||||
|
||||
def json_contains(column: ColumnElement, value: Any) -> ColumnElement:
|
||||
"""
|
||||
JSON 数组包含检查(跨数据库兼容)
|
||||
|
||||
检查 JSON 数组列是否包含指定值
|
||||
|
||||
PostgreSQL: 使用 JSONB 的 @> 操作符
|
||||
MySQL: 使用 JSON_CONTAINS 函数
|
||||
SQL Server: 使用 OPENJSON + EXISTS 子查询
|
||||
|
||||
Args:
|
||||
column: JSON 类型的列
|
||||
value: 要检查的值(会被转换为 JSON 数组)
|
||||
|
||||
Returns:
|
||||
SQLAlchemy 条件表达式
|
||||
|
||||
Example:
|
||||
# 检查 target_ids 是否包含 "user123"
|
||||
json_contains(Announcement.target_ids, "user123")
|
||||
"""
|
||||
db_type = get_db_type()
|
||||
|
||||
if db_type == "mysql":
|
||||
# MySQL: JSON_CONTAINS(column, JSON_ARRAY(value))
|
||||
import json
|
||||
json_value = json.dumps([value] if not isinstance(value, list) else value)
|
||||
return func.json_contains(column, json_value)
|
||||
elif db_type == "sqlserver":
|
||||
# SQL Server: 使用 LIKE 进行简单匹配(JSON 数组中包含元素)
|
||||
# 注意: 这是简化实现,适用于简单字符串值
|
||||
import json
|
||||
search_value = json.dumps(value)
|
||||
return column.like(f'%{search_value}%')
|
||||
else:
|
||||
# PostgreSQL: cast to JSONB and use contains
|
||||
from sqlalchemy import cast
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
|
||||
target_value = [value] if not isinstance(value, list) else value
|
||||
return cast(column, JSONB).contains(cast(target_value, JSONB))
|
||||
|
||||
|
||||
def json_extract(column: ColumnElement, key: str) -> ColumnElement:
|
||||
"""
|
||||
从 JSON 对象中提取值(跨数据库兼容)
|
||||
|
||||
PostgreSQL: 使用 JSONB 的 ->> 操作符
|
||||
MySQL: 使用 JSON_EXTRACT 和 JSON_UNQUOTE 函数
|
||||
SQL Server: 使用 JSON_VALUE 函数
|
||||
|
||||
Args:
|
||||
column: JSON 类型的列
|
||||
key: 要提取的键名
|
||||
|
||||
Returns:
|
||||
提取的值(作为文本)
|
||||
|
||||
Example:
|
||||
# 提取 extra_metadata 中的 "author" 字段
|
||||
json_extract(KnowledgeSegment.extra_metadata, "author")
|
||||
"""
|
||||
db_type = get_db_type()
|
||||
|
||||
if db_type == "mysql":
|
||||
# MySQL: JSON_UNQUOTE(JSON_EXTRACT(column, '$.key'))
|
||||
return func.json_unquote(func.json_extract(column, f"$.{key}"))
|
||||
elif db_type == "sqlserver":
|
||||
# SQL Server: JSON_VALUE(column, '$.key')
|
||||
return func.json_value(column, f"$.{key}")
|
||||
else:
|
||||
# PostgreSQL: cast to JSONB and use ->> operator
|
||||
from sqlalchemy import cast
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
|
||||
return cast(column, JSONB)[key].astext
|
||||
|
||||
|
||||
def json_has_key(column: ColumnElement, key: str) -> ColumnElement:
|
||||
"""
|
||||
检查 JSON 对象是否包含指定键(跨数据库兼容)
|
||||
|
||||
PostgreSQL: 使用 JSONB 的 ? 操作符
|
||||
MySQL: 使用 JSON_CONTAINS_PATH 函数
|
||||
SQL Server: 使用 JSON_VALUE IS NOT NULL
|
||||
|
||||
Args:
|
||||
column: JSON 类型的列
|
||||
key: 要检查的键名
|
||||
|
||||
Returns:
|
||||
SQLAlchemy 条件表达式
|
||||
|
||||
Example:
|
||||
# 检查 extra_metadata 是否包含 "author" 键
|
||||
json_has_key(KnowledgeSegment.extra_metadata, "author")
|
||||
"""
|
||||
db_type = get_db_type()
|
||||
|
||||
if db_type == "mysql":
|
||||
# MySQL: JSON_CONTAINS_PATH(column, 'one', '$.key')
|
||||
return func.json_contains_path(column, "one", f"$.{key}")
|
||||
elif db_type == "sqlserver":
|
||||
# SQL Server: JSON_VALUE(column, '$.key') IS NOT NULL
|
||||
return func.json_value(column, f"$.{key}").isnot(None)
|
||||
else:
|
||||
# PostgreSQL: cast to JSONB and use has_key
|
||||
from sqlalchemy import cast
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
|
||||
return cast(column, JSONB).has_key(key)
|
||||
|
||||
|
||||
def json_array_contains_any(column: ColumnElement, values: List[Any]) -> List[ColumnElement]:
|
||||
"""
|
||||
生成多个 JSON 数组包含检查条件(用于 OR 组合)
|
||||
|
||||
Args:
|
||||
column: JSON 类型的列
|
||||
values: 要检查的值列表
|
||||
|
||||
Returns:
|
||||
条件表达式列表,可用于 or_() 组合
|
||||
|
||||
Example:
|
||||
# 检查 target_ids 是否包含任意一个 dept_id
|
||||
conditions = json_array_contains_any(Announcement.target_ids, dept_ids)
|
||||
query.where(or_(*conditions))
|
||||
"""
|
||||
return [json_contains(column, value) for value in values]
|
||||
Reference in New Issue
Block a user