diff --git a/apps/function_lib/migrations/0003_functionlib_function_type_functionlib_icon_and_more.py b/apps/function_lib/migrations/0003_functionlib_function_type_functionlib_icon_and_more.py
index beb5ac3bb..f7e1aa4cc 100644
--- a/apps/function_lib/migrations/0003_functionlib_function_type_functionlib_icon_and_more.py
+++ b/apps/function_lib/migrations/0003_functionlib_function_type_functionlib_icon_and_more.py
@@ -114,7 +114,49 @@ INSERT INTO function_lib (create_time, update_time, id, name, "desc", code, inpu
cursor.close()
if conn:
conn.close()
-', '{"{\"name\": \"query\", \"type\": \"string\", \"source\": \"reference\", \"is_required\": true}"}', 'f0dd8f71-e4ee-11ee-8c84-a8a1595801ab', true, 'PUBLIC', 'INTERNAL', '/src/assets/fx/postgresql/icon.png', '[{"attrs": {"maxlength": 200, "minlength": 1, "show-word-limit": true}, "field": "dbname", "label": "dbname", "required": true, "input_type": "TextInput", "props_info": {"rules": [{"message": "dbname 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "dbname长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}, {"attrs": {"maxlength": 200, "minlength": 1, "show-word-limit": true}, "field": "user", "label": "user", "required": true, "input_type": "TextInput", "props_info": {"rules": [{"message": "user 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "user长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}, {"attrs": {"type": "password", "maxlength": 200, "minlength": 1, "show-password": true, "show-word-limit": true}, "field": "password", "label": "password", "required": true, "input_type": "PasswordInput", "props_info": {"rules": [{"message": "password 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "password长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}, {"attrs": {"maxlength": 200, "minlength": 1, "show-word-limit": true}, "field": "host", "label": "host", "required": true, "input_type": "TextInput", "props_info": {"rules": [{"message": "host 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "host长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}, {"attrs": {"maxlength": 20, "minlength": 1, "show-word-limit": true}, "field": "port", "label": "port", "required": true, "input_type": "TextInput", "props_info": {"rules": [{"message": "port 为必填属性", "required": true}, {"max": 20, "min": 1, "message": "port长度在 1 到 20 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}]', null, null);
+', '{"{\"name\": \"dbname\", \"type\": \"string\", \"source\": \"custom\", \"is_required\": true}","{\"name\": \"user\", \"type\": \"string\", \"source\": \"custom\", \"is_required\": true}","{\"name\": \"password\", \"type\": \"string\", \"source\": \"custom\", \"is_required\": true}","{\"name\": \"host\", \"type\": \"string\", \"source\": \"custom\", \"is_required\": true}","{\"name\": \"port\", \"type\": \"string\", \"source\": \"custom\", \"is_required\": true}","{\"name\": \"query\", \"type\": \"string\", \"source\": \"reference\", \"is_required\": true}"}', 'f0dd8f71-e4ee-11ee-8c84-a8a1595801ab', true, 'PUBLIC', 'INTERNAL', '/src/assets/fx/postgresql/icon.png', '[]', null, null);
+INSERT INTO function_lib (create_time, update_time, id, name, "desc", code, input_field_list, user_id, is_active, permission_type, function_type, icon, init_field_list, init_params, template_id) VALUES ('2025-03-17 08:16:32.626245 +00:00', '2025-03-17 08:16:32.626308 +00:00', '22c21b76-0308-11f0-9694-5618c4394482', 'MySQL 查询', '', e'
+def query_mysql(host,port, user, password, database, sql):
+ import pymysql
+ import json
+ from pymysql.cursors import DictCursor
+
+ try:
+ # 创建连接
+ db = pymysql.connect(
+ host=host,
+ port=int(port),
+ user=user,
+ password=password,
+ database=database,
+ cursorclass=DictCursor # 使用字典游标
+ )
+
+ # 使用 cursor() 方法创建一个游标对象 cursor
+ cursor = db.cursor()
+
+ # 使用 execute() 方法执行 SQL 查询
+ cursor.execute(sql)
+
+ # 使用 fetchall() 方法获取所有数据
+ data = cursor.fetchall()
+
+ # 处理 bytes 类型的数据
+ for row in data:
+ for key, value in row.items():
+ if isinstance(value, bytes):
+ row[key] = value.decode(\"utf-8\") # 转换为字符串
+
+ # 将数据序列化为 JSON
+ json_data = json.dumps(data, ensure_ascii=False)
+ print(json_data)
+ return json_data
+
+ # 关闭数据库连接
+ db.close()
+
+ except Exception as e:
+ print(f"Error while connecting to MySQL: {e}")', '{"{\"name\": \"host\", \"type\": \"string\", \"source\": \"custom\", \"is_required\": true}","{\"name\": \"port\", \"type\": \"string\", \"source\": \"custom\", \"is_required\": true}","{\"name\": \"user\", \"type\": \"string\", \"source\": \"custom\", \"is_required\": true}","{\"name\": \"password\", \"type\": \"string\", \"source\": \"custom\", \"is_required\": true}","{\"name\": \"database\", \"type\": \"string\", \"source\": \"custom\", \"is_required\": true}","{\"name\": \"sql\", \"type\": \"string\", \"source\": \"reference\", \"is_required\": true}"}', 'f0dd8f71-e4ee-11ee-8c84-a8a1595801ab', true, 'PUBLIC', 'INTERNAL', '/src/assets/fx/mysql/icon.png', '[]', null, null);
'''
diff --git a/pyproject.toml b/pyproject.toml
index ef59898c4..863cc3434 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -62,6 +62,7 @@ cffi = "^1.17.1"
pysilk = "^0.0.1"
django-db-connection-pool = "^1.2.5"
opencv-python-headless = "^4.11.0.86"
+pymysql = "^1.1.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
diff --git a/ui/src/assets/fx/mysql/icon.png b/ui/src/assets/fx/mysql/icon.png
new file mode 100644
index 000000000..90cb9a902
Binary files /dev/null and b/ui/src/assets/fx/mysql/icon.png differ
diff --git a/ui/src/assets/fx/mysql/index.vue b/ui/src/assets/fx/mysql/index.vue
new file mode 100644
index 000000000..c03b178d7
--- /dev/null
+++ b/ui/src/assets/fx/mysql/index.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
详情
+
+
+
+
+
+
\ No newline at end of file