feat: execute sql

This commit is contained in:
junjun
2025-05-13 11:35:05 +08:00
parent 97341631e5
commit 4fe3a7502f
5 changed files with 87 additions and 42 deletions
+6 -1
View File
@@ -1,5 +1,5 @@
from fastapi import APIRouter
from ..crud.datasource import get_datasource_list, check_status, create_ds, update_ds, delete_ds, getTables, getFields
from ..crud.datasource import get_datasource_list, check_status, create_ds, update_ds, delete_ds, getTables, getFields, execSql
from common.core.deps import SessionDep
from ..models.datasource import CoreDatasource
@@ -39,3 +39,8 @@ async def get_tables(session: SessionDep, id: int):
@router.post("/getFields/{id}/{table_name}")
async def get_tables(session: SessionDep, id: int, table_name: str):
return getFields(session, id, table_name)
@router.post("/execSql/{id}/{sql}")
async def exec_sql(session: SessionDep, id: int, sql: str):
return execSql(session, id, sql)
+9 -9
View File
@@ -2,9 +2,7 @@ from sqlmodel import select
from ..models.datasource import CoreDatasource, DatasourceConf
import datetime
from common.core.deps import SessionDep
import json
from ..utils.utils import aes_decrypt
from apps.db.db import get_session, get_tables, get_fields
from apps.db.db import get_session, get_tables, get_fields, exec_sql
from sqlalchemy import text
@@ -15,8 +13,7 @@ def get_datasource_list(session: SessionDep) -> CoreDatasource:
def check_status(session: SessionDep, ds: CoreDatasource):
conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration)))
conn = get_session(conf, ds)
conn = get_session(ds)
try:
conn.execute(text("SELECT 1")).scalar()
print("success")
@@ -59,13 +56,16 @@ def delete_ds(session: SessionDep, id: int):
def getTables(session: SessionDep, id: int):
ds = session.exec(select(CoreDatasource).where(CoreDatasource.id == id)).first()
conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration)))
tables = get_tables(conf, ds)
tables = get_tables(ds)
return tables
def getFields(session: SessionDep, id: int, table_name: str):
ds = session.exec(select(CoreDatasource).where(CoreDatasource.id == id)).first()
conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration)))
fields = get_fields(conf, ds, table_name)
fields = get_fields(ds, table_name)
return fields
def execSql(session: SessionDep, id: int, sql: str):
ds = session.exec(select(CoreDatasource).where(CoreDatasource.id == id)).first()
return exec_sql(ds, sql)
+66 -31
View File
@@ -3,9 +3,12 @@ from sqlalchemy.orm import sessionmaker
from apps.datasource.models.datasource import DatasourceConf, CoreDatasource, TableSchema, ColumnSchema
import urllib.parse
from typing import Any
import json
from apps.datasource.utils.utils import aes_decrypt
def get_session(conf: DatasourceConf, ds: CoreDatasource):
def get_session(ds: CoreDatasource):
conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration)))
db_url: str
if ds.type == "mysql":
db_url = f"mysql+pymysql://{urllib.parse.quote(conf.username)}:{urllib.parse.quote(conf.password)}@{conf.host}:{conf.port}/{urllib.parse.quote(conf.database)}"
@@ -17,39 +20,71 @@ def get_session(conf: DatasourceConf, ds: CoreDatasource):
return session
def get_tables(conf: DatasourceConf, ds: CoreDatasource):
session = get_session(conf, ds)
def get_tables(ds: CoreDatasource):
conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration)))
session = get_session(ds)
result: Result[Any]
if ds.type == "mysql":
sql = f"""SELECT
TABLE_NAME,
TABLE_COMMENT
FROM
information_schema.TABLES
WHERE
TABLE_SCHEMA = '{conf.database}';"""
result = session.execute(text(sql))
try:
if ds.type == "mysql":
sql = f"""SELECT
TABLE_NAME,
TABLE_COMMENT
FROM
information_schema.TABLES
WHERE
TABLE_SCHEMA = '{conf.database}';"""
result = session.execute(text(sql))
res = result.fetchall()
res_list = [TableSchema(*item) for item in res]
return res_list
res = result.fetchall()
res_list = [TableSchema(*item) for item in res]
return res_list
finally:
if result is not None:
result.close()
if session is not None:
session.close()
def get_fields(conf: DatasourceConf, ds: CoreDatasource, table_name: str):
session = get_session(conf, ds)
def get_fields(ds: CoreDatasource, table_name: str):
conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration)))
session = get_session(ds)
result: Result[Any]
if ds.type == "mysql":
sql = f"""SELECT
COLUMN_NAME,
DATA_TYPE,
COLUMN_COMMENT
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = '{conf.database}' AND
TABLE_NAME = '{table_name}';"""
result = session.execute(text(sql))
try:
if ds.type == "mysql":
sql = f"""SELECT
COLUMN_NAME,
DATA_TYPE,
COLUMN_COMMENT
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = '{conf.database}' AND
TABLE_NAME = '{table_name}';"""
result = session.execute(text(sql))
res = result.fetchall()
res_list = [ColumnSchema(*item) for item in res]
return res_list
res = result.fetchall()
res_list = [ColumnSchema(*item) for item in res]
return res_list
finally:
if result is not None:
result.close()
if session is not None:
session.close()
def exec_sql(ds: CoreDatasource, sql: str):
session = get_session(ds)
result = session.execute(text(sql))
try:
columns = result.keys()._keys
res = result.fetchall()
result_list = [
{columns[i]: value for i, value in enumerate(tuple_item)}
for tuple_item in res
]
return {"fields": columns, "data": result_list}
finally:
if result is not None:
result.close()
if session is not None:
session.close()
+1
View File
@@ -8,4 +8,5 @@ export const datasourceApi = {
delete: (id: Number) => request.post(`/datasource/delete/${id}`),
getTables: (id: Number) => request.post(`/datasource/getTables/${id}`),
getFields: (id: Number, table_name: string) => request.post(`/datasource/getFields/${id}/${table_name}`),
execSql: (id: Number, sql: string) => request.post(`/datasource/execSql/${id}/${sql}`),
}
+5 -1
View File
@@ -120,7 +120,11 @@ const getTables = (id: Number) => {
// console.log(res)
// })
datasourceApi.getFields(id,'core_dataset_table').then((res) => {
// datasourceApi.getFields(id,'core_dataset_table').then((res) => {
// console.log(res)
// })
datasourceApi.execSql(id,'select id,name,table_name from core_dataset_table limit 10').then((res) => {
console.log(res)
})
}