Skip to content

Commit

Permalink
update sqlalchemy support
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangyongchao committed Jan 24, 2025
1 parent b52fb2d commit 381e32e
Show file tree
Hide file tree
Showing 10 changed files with 394 additions and 975 deletions.
137 changes: 54 additions & 83 deletions lazyllm/docs/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -1439,62 +1439,7 @@
"""\
SqlManager是与数据库进行交互的专用工具。它提供了连接数据库,设置、创建、检查数据表,插入数据,执行查询的方法。
Arguments:
db_type (str): 目前仅支持"PostgreSQL",后续会增加"MySQL", "MS SQL"
user (str): username
password (str): password
host (str): 主机名或IP
port (int): 端口号
db_name (str): 数据仓库名
tables_info_dict (dict): 数据表的描述
options_str (str): k1=v1&k2=v2形式表示的选项设置
""",
)

add_english_doc(
"SqlManager",
"""\
SqlManager is a specialized tool for interacting with databases.
It provides methods for creating tables, executing queries, and performing updates on databases.
Arguments:
db_type (str): Currently only "PostgreSQL" is supported, with "MySQL" and "MS SQL" to be added later.
user (str): Username for connection
password (str): Password for connection
host (str): Hostname or IP
port (int): Port number
db_name (str): Name of the database
tables_info_dict (dict): Description of the data tables
options_str (str): Options represented in the format k1=v1&k2=v2
""",
)

add_example(
"SqlManager",
"""\
>>> from lazyllm.tools import SqlManager
>>> import uuid
>>> # !!!NOTE!!!: COPY class SqlEgsData definition from tests/charge_tests/utils.py then Paste here.
>>> db_filepath = "personal.db"
>>> with open(db_filepath, "w") as _:
pass
>>> sql_manager = SQLiteManger(filepath, SqlEgsData.TEST_TABLES_INFO)
>>> # Altert: If using online database, ask administrator about those value: db_type, username, password, host, port, database
>>> # sql_manager = SqlManager(db_type, username, password, host, port, database, SqlEgsData.TEST_TABLES_INFO)
>>>
>>> for insert_script in SqlEgsData.TEST_INSERT_SCRIPTS:
... sql_manager.execute_sql_update(insert_script)
>>> str_results = sql_manager.get_query_result_in_json(SqlEgsData.TEST_QUERY_SCRIPTS)
>>> print(str_results)
""",
)

add_chinese_doc(
"SqlManager.reset_table_info_dict",
"""\
根据描述表结构的字典设置SqlManager所使用的数据表。注意:若表在数据库中不存在将会自动创建,若存在则会校验所有字段的一致性。
字典格式关键字示例如下。
tables_info_dict字典格式关键字示例如下。
字典中有3个关键字为可选项:表及列的comment默认为空, is_primary_key默认为False但至少应有一列为True, nullable默认为True
{"tables":
[
Expand All @@ -1518,16 +1463,26 @@
}
]
}
Arguments:
db_type (str): 目前仅支持"PostgreSQL",后续会增加"MySQL", "MS SQL"
user (str): username
password (str): password
host (str): 主机名或IP
port (int): 端口号
db_name (str): 数据仓库名
tables_info_dict (dict): 数据表的描述
options_str (str): k1=v1&k2=v2形式表示的选项设置
""",
)

add_english_doc(
"SqlManager.reset_table_info_dict",
"SqlManager",
"""\
Set the data tables used by SqlManager according to the dictionary describing the table structure.
Note that if the table does not exist in the database, it will be automatically created, and if it exists, all field consistencies will be checked.
The dictionary format keyword example is as follows.
SqlManager is a specialized tool for interacting with databases.
It provides methods for creating tables, executing queries, and performing updates on databases.
The dictionary format of tables_info_dict is as follows.
There are three optional keywords in the dictionary: "comment" for the table and columns defaults to empty, "is_primary_key" defaults to False,
but at least one column should be True, and "nullable" defaults to True.
{"tables":
Expand All @@ -1552,13 +1507,43 @@
}
]
}
Arguments:
db_type (str): Currently only "PostgreSQL" is supported, with "MySQL" and "MS SQL" to be added later.
user (str): Username for connection
password (str): Password for connection
host (str): Hostname or IP
port (int): Port number
db_name (str): Name of the database
tables_info_dict (dict): Description of the data tables
options_str (str): Options represented in the format k1=v1&k2=v2
""",
)

add_example(
"SqlManager",
"""\
>>> from lazyllm.tools import SqlManager
>>> import uuid
>>> # !!!NOTE!!!: COPY class SqlEgsData definition from tests/charge_tests/utils.py then Paste here.
>>> db_filepath = "personal.db"
>>> with open(db_filepath, "w") as _:
pass
>>> sql_manager = SQLiteManger(filepath, SqlEgsData.TEST_TABLES_INFO)
>>> # Altert: If using online database, ask administrator about those value: db_type, username, password, host, port, database
>>> # sql_manager = SqlManager(db_type, username, password, host, port, database, SqlEgsData.TEST_TABLES_INFO)
>>>
>>> for insert_script in SqlEgsData.TEST_INSERT_SCRIPTS:
... sql_manager.execute_sql_update(insert_script)
>>> str_results = sql_manager.get_query_result_in_json(SqlEgsData.TEST_QUERY_SCRIPTS)
>>> print(str_results)
""",
)

add_chinese_doc(
"SqlManagerBase",
"SqlBase",
"""\
SqlManagerBase是与数据库进行交互的专用工具。它提供了连接数据库,设置、创建、检查数据表,插入数据,执行查询的方法。
SqlBase是与数据库进行交互的专用工具。它提供了连接数据库,设置、创建、检查数据表,插入数据,执行查询的方法。
Arguments:
db_type (str): 目前仅支持"PostgreSQL",后续会增加"MySQL", "MS SQL"
Expand All @@ -1573,9 +1558,9 @@
)

add_english_doc(
"SqlManagerBase",
"SqlBase",
"""\
SqlManagerBase is a specialized tool for interacting with databases.
SqlBase is a specialized tool for interacting with databases.
It provides methods for creating tables, executing queries, and performing updates on databases.
Arguments:
Expand All @@ -1591,9 +1576,9 @@
)

add_chinese_doc(
"SqlManagerBase.check_connection",
"SqlBase.check_connection",
"""\
检查当前SqlManagerBase的连接状态
检查当前SqlBase的连接状态
**Returns:**\n
- bool: 连接成功(True), 连接失败(False)
Expand All @@ -1602,7 +1587,7 @@
)

add_english_doc(
"SqlManagerBase.check_connection",
"SqlBase.check_connection",
"""\
Check the current connection status of the SqlManagerBase.
Expand All @@ -1613,33 +1598,19 @@
)

add_chinese_doc(
"SqlManagerBase.execute_to_json",
"SqlBase.execute_to_json",
"""\
执行SQL查询并返回JSON格式的结果。
""",
)

add_english_doc(
"SqlManagerBase.execute_to_json",
"SqlBase.execute_to_json",
"""\
Executes a SQL query and returns the result in JSON format.
""",
)

add_chinese_doc(
"SqlManagerBase.execute",
"""\
在SQLite数据库上执行SQL插入或更新脚本。
""",
)

add_english_doc(
"SqlManagerBase.execute",
"""\
Execute insert or update script.
""",
)

add_chinese_doc(
"SqlCall",
"""\
Expand Down
5 changes: 2 additions & 3 deletions lazyllm/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
ReWOOAgent,
)
from .classifier import IntentClassifier
from .sql import SqlManagerBase, SQLiteManger, SqlManager, MongoDBManager, DBResult, DBStatus
from .sql import SqlBase, SqlManager, MongoDBManager, DBResult, DBStatus
from .sql_call import SqlCall
from .tools.http_tool import HttpTool

Expand All @@ -29,8 +29,7 @@
"ReWOOAgent",
"IntentClassifier",
"SentenceSplitter",
"SqlManagerBase",
"SQLiteManger",
"SqlBase",
"SqlManager",
"MongoDBManager",
"DBResult",
Expand Down
4 changes: 2 additions & 2 deletions lazyllm/tools/sql/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .sql_manager import SqlManager, SqlManagerBase, SQLiteManger
from .sql_manager import SqlManager, SqlBase
from .mongodb_manager import MongoDBManager
from .db_manager import DBManager, DBResult, DBStatus

__all__ = ["DBManager", "SqlManagerBase", "SQLiteManger", "SqlManager", "MongoDBManager", "DBResult", "DBStatus"]
__all__ = ["DBManager", "SqlBase", "SqlManager", "MongoDBManager", "DBResult", "DBStatus"]
67 changes: 27 additions & 40 deletions lazyllm/tools/sql/db_manager.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from enum import Enum, unique
from typing import List, Union, overload
from typing import List, Union
from pydantic import BaseModel
from abc import ABC, abstractmethod
from urllib.parse import quote_plus


@unique
Expand All @@ -16,55 +15,43 @@ class DBResult(BaseModel):
detail: str = "Success"
result: Union[List, None] = None


class DBManager(ABC):
DB_TYPE_SUPPORTED = set(["postgresql", "mysql", "mssql", "sqlite", "mongodb"])
DB_DRIVER_MAP = {"mysql": "pymysql"}

def __init__(
self,
db_type: str,
user: str,
password: str,
host: str,
port: int,
db_name: str,
options_str: str = "",
) -> None:
password = quote_plus(password)
self.status = DBStatus.SUCCESS
self.detail = ""
def __init__(self, db_type: str):
db_type = db_type.lower()
db_result = self.reset_engine(db_type, user, password, host, port, db_name, options_str)
if db_result.status != DBStatus.SUCCESS:
raise ValueError(db_result.detail)

@overload
def reset_engine(self, db_type, user, password, host, port, db_name, options_str) -> DBResult:
pass
if db_type not in self.DB_TYPE_SUPPORTED:
raise ValueError(f"{db_type} not supported")
self._db_type = db_type
self._desc = None

@abstractmethod
def execute_to_json(self, statement):
def execute_to_json(self, statement) -> str:
pass

@property
def db_type(self):
def db_type(self) -> str:
return self._db_type

@property
def desc(self):
return self._desc

def _is_str_or_nested_dict(self, value):
if isinstance(value, str):
return True
elif isinstance(value, dict):
return all(self._is_str_or_nested_dict(v) for v in value.values())
return False

def _validate_desc(self, d):
return isinstance(d, dict) and all(self._is_str_or_nested_dict(v) for v in d.values())

def _serialize_uncommon_type(self, obj):
@abstractmethod
def desc(self) -> str: pass

@staticmethod
def _is_dict_all_str(d):
if not isinstance(d, dict):
return False
for key, value in d.items():
if not isinstance(key, str):
return False
if isinstance(value, dict):
if not DBManager._is_dict_all_str(value):
return False
elif not isinstance(value, str):
return False
return True

@staticmethod
def _serialize_uncommon_type(obj):
if not isinstance(obj, int, str, float, bool, tuple, list, dict):
return str(obj)
Loading

0 comments on commit 381e32e

Please sign in to comment.