diff --git a/backend/apps/datasource/api/datasource.py b/backend/apps/datasource/api/datasource.py index 5cda29b7..afd7595d 100644 --- a/backend/apps/datasource/api/datasource.py +++ b/backend/apps/datasource/api/datasource.py @@ -1,4 +1,4 @@ -from fastapi import APIRouter +from fastapi import APIRouter, File, UploadFile from ..crud.datasource import get_datasource_list, check_status, create_ds, update_ds, delete_ds, getTables, getFields, \ execSql, update_table_and_fields, getTablesByDs, chooseTables, preview from common.core.deps import SessionDep @@ -78,3 +78,9 @@ async def edit_local(session: SessionDep, data: EditObj): @router.post("/previewData/{id}") async def edit_local(session: SessionDep, id: int, data: EditObj): return preview(session, id, data) + + +@router.post("/uploadExcel/") +async def upload_excel(session: SessionDep, file: UploadFile = File(...)): + # todo + pass diff --git a/backend/apps/datasource/models/datasource.py b/backend/apps/datasource/models/datasource.py index a571a3ec..18352d97 100644 --- a/backend/apps/datasource/models/datasource.py +++ b/backend/apps/datasource/models/datasource.py @@ -66,6 +66,7 @@ class DatasourceConf(BaseModel): password: str = '' database: str = '' driver: str = '' + extraJdbc: str = '' class TableSchema: diff --git a/backend/apps/db/db.py b/backend/apps/db/db.py index 4fdb52a6..24d4ca38 100644 --- a/backend/apps/db/db.py +++ b/backend/apps/db/db.py @@ -1,31 +1,29 @@ -from sqlalchemy import create_engine, text, Result -from sqlalchemy.orm import sessionmaker -from apps.datasource.models.datasource import DatasourceConf, CoreDatasource, TableSchema, ColumnSchema +import json import urllib.parse from typing import Any -import json + +from sqlalchemy import create_engine, text, Result +from sqlalchemy.orm import sessionmaker + +from apps.datasource.models.datasource import DatasourceConf, CoreDatasource, TableSchema, ColumnSchema from apps.datasource.utils.utils import aes_decrypt -from common.core.deps import SessionDep def get_uri(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)}" + if conf.extraJdbc is not None and conf.extraJdbc != '': + db_url = f"mysql+pymysql://{urllib.parse.quote(conf.username)}:{urllib.parse.quote(conf.password)}@{conf.host}:{conf.port}/{urllib.parse.quote(conf.database)}?{urllib.parse.quote(conf.extraJdbc)}" + else: + db_url = f"mysql+pymysql://{urllib.parse.quote(conf.username)}:{urllib.parse.quote(conf.password)}@{conf.host}:{conf.port}/{urllib.parse.quote(conf.database)}" else: raise 'The datasource type not support.' return db_url 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)}" - else: - raise 'The datasource type not support.' - engine = create_engine(db_url) + engine = create_engine(get_uri(ds)) session_maker = sessionmaker(bind=engine) session = session_maker() return session @@ -100,4 +98,3 @@ def exec_sql(ds: CoreDatasource, sql: str): result.close() if session is not None: session.close() - diff --git a/frontend/src/views/ds/form.vue b/frontend/src/views/ds/form.vue index 05e429f9..d21094b2 100644 --- a/frontend/src/views/ds/form.vue +++ b/frontend/src/views/ds/form.vue @@ -44,6 +44,9 @@ + + +
@@ -106,6 +109,7 @@ const config = ref({ username:'', password:'', database:'', + extraJdbc:'' }) const close = () => { @@ -133,6 +137,7 @@ const open = (item: any, editTable: boolean = false) => { config.value.username = configuration.username config.value.password = configuration.password config.value.database = configuration.database + config.value.extraJdbc = configuration.extraJdbc } if (editTable) { @@ -165,6 +170,7 @@ const open = (item: any, editTable: boolean = false) => { username:'', password:'', database:'', + extraJdbc:'', } } dialogVisible.value = true @@ -178,13 +184,7 @@ const save = async(formEl: FormInstance | undefined) => { .filter((ele: any) => {return checkList.value.includes(ele.tableName)}) .map((ele: any) => {return {"table_name": ele.tableName, "table_comment": ele.tableComment}}) - form.value.configuration = encrypted(JSON.stringify({ - host:config.value.host, - port:config.value.port, - username:config.value.username, - password:config.value.password, - database:config.value.database - })) + buildConf() if (form.value.id) { if (!isEditTable.value) { // only update datasource config info @@ -217,7 +217,8 @@ const buildConf = () => { port:config.value.port, username:config.value.username, password:config.value.password, - database:config.value.database + database:config.value.database, + extraJdbc:config.value.extraJdbc })) } diff --git a/frontend/src/views/ds/index.vue b/frontend/src/views/ds/index.vue index 455e3764..2e0cbdd5 100644 --- a/frontend/src/views/ds/index.vue +++ b/frontend/src/views/ds/index.vue @@ -25,7 +25,9 @@ v-for="ds in dsList" >
- + + +
{{ ds.name }}
@@ -49,6 +51,7 @@ import IconOpeAdd from '@/assets/svg/operate/ope-add.svg' import IconOpeEdit from '@/assets/svg/operate/ope-edit.svg' import IconOpeDelete from '@/assets/svg/operate/ope-delete.svg' +import MysqlDs from '@/assets/svg/ds/mysql-ds.svg' import { Search, List, CreditCard } from '@element-plus/icons-vue' import { ref, onMounted } from 'vue' import DsForm from './form.vue'