Skip to content

Commit 17874ac

Browse files
committed
feat: support DM datasource
1 parent b0cb0da commit 17874ac

File tree

9 files changed

+306
-205
lines changed

9 files changed

+306
-205
lines changed

backend/apps/datasource/crud/datasource.py

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
import json
33
from typing import List, Optional
44

5+
import dmPython
56
from fastapi import HTTPException
67
from sqlalchemy import and_, text
78
from sqlmodel import select
89

910
from apps.datasource.crud.permission import get_column_permission_fields, get_row_permission_filters, is_normal_user
1011
from apps.datasource.utils.utils import aes_decrypt
12+
from apps.db.constant import ConnectType
1113
from apps.db.constant import DB
1214
from apps.db.db import get_engine, get_tables, get_fields, exec_sql
1315
from apps.db.engine import get_engine_config, get_engine_conn
@@ -45,16 +47,32 @@ def check_status_by_id(session: SessionDep, trans: Trans, ds_id: int, is_raise:
4547

4648

4749
def check_status(session: SessionDep, trans: Trans, ds: CoreDatasource, is_raise: bool = False):
48-
conn = get_engine(ds, 10)
49-
try:
50-
with conn.connect() as connection:
51-
SQLBotLogUtil.info("success")
52-
return True
53-
except Exception as e:
54-
SQLBotLogUtil.error(f"Datasource {ds.id} connection failed: {e}")
55-
if is_raise:
56-
raise HTTPException(status_code=500, detail=trans('i18n_ds_invalid') + f': {e.args}')
57-
return False
50+
db = DB.get_db(ds.type)
51+
if db.connect_type == ConnectType.sqlalchemy:
52+
conn = get_engine(ds, 10)
53+
try:
54+
with conn.connect() as connection:
55+
SQLBotLogUtil.info("success")
56+
return True
57+
except Exception as e:
58+
SQLBotLogUtil.error(f"Datasource {ds.id} connection failed: {e}")
59+
if is_raise:
60+
raise HTTPException(status_code=500, detail=trans('i18n_ds_invalid') + f': {e.args}')
61+
return False
62+
else:
63+
conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration)))
64+
if ds.type == 'dm':
65+
with dmPython.connect(user=conf.username, password=conf.password, server=conf.host,
66+
port=conf.port) as conn, conn.cursor() as cursor:
67+
try:
68+
cursor.execute('select 1').fetchall()
69+
SQLBotLogUtil.info("success")
70+
return True
71+
except Exception as e:
72+
SQLBotLogUtil.error(f"Datasource {ds.id} connection failed: {e}")
73+
if is_raise:
74+
raise HTTPException(status_code=500, detail=trans('i18n_ds_invalid') + f': {e.args}')
75+
return False
5876

5977

6078
def check_name(session: SessionDep, trans: Trans, user: CurrentUser, ds: CoreDatasource):
@@ -159,7 +177,7 @@ def getFieldsByDs(session: SessionDep, ds: CoreDatasource, table_name: str):
159177

160178
def execSql(session: SessionDep, id: int, sql: str):
161179
ds = session.exec(select(CoreDatasource).where(CoreDatasource.id == id)).first()
162-
return exec_sql(ds, sql)
180+
return exec_sql(ds, sql, True)
163181

164182

165183
def sync_table(session: SessionDep, ds: CoreDatasource, tables: List[CoreTable]):
@@ -297,7 +315,11 @@ def preview(session: SessionDep, current_user: CurrentUser, id: int, data: Table
297315
sql = f"""SELECT "{'", "'.join(fields)}" FROM "{data.table.table_name}"
298316
{where}
299317
LIMIT 100"""
300-
return exec_sql(ds, sql)
318+
elif ds.type == "dm":
319+
sql = f"""SELECT "{'", "'.join(fields)}" FROM "{conf.dbSchema}"."{data.table.table_name}"
320+
{where}
321+
LIMIT 100"""
322+
return exec_sql(ds, sql, True)
301323

302324

303325
def fieldEnum(session: SessionDep, id: int):
@@ -313,7 +335,7 @@ def fieldEnum(session: SessionDep, id: int):
313335

314336
db = DB.get_db(ds.type)
315337
sql = f"""SELECT DISTINCT {db.prefix}{field.field_name}{db.suffix} FROM {db.prefix}{table.table_name}{db.suffix}"""
316-
res = exec_sql(ds, sql)
338+
res = exec_sql(ds, sql, True)
317339
return [item.get(res.get('fields')[0]) for item in res.get('data')]
318340

319341

backend/apps/db/constant.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,28 @@
44
from enum import Enum
55

66

7+
class ConnectType(Enum):
8+
sqlalchemy = ('sqlalchemy')
9+
py_driver = ('py_driver')
10+
11+
def __init__(self, type_name):
12+
self.type_name = type_name
13+
14+
715
class DB(Enum):
8-
mysql = ('mysql', '`', '`')
9-
sqlServer = ('sqlServer', '[', ']')
10-
pg = ('pg', '"', '"')
11-
excel = ('excel', '"', '"')
12-
oracle = ('oracle', '"', '"')
13-
ck = ('ClickHouse', '"', '"')
14-
15-
def __init__(self, type, prefix, suffix):
16+
mysql = ('mysql', '`', '`', ConnectType.sqlalchemy)
17+
sqlServer = ('sqlServer', '[', ']', ConnectType.sqlalchemy)
18+
pg = ('pg', '"', '"', ConnectType.sqlalchemy)
19+
excel = ('excel', '"', '"', ConnectType.sqlalchemy)
20+
oracle = ('oracle', '"', '"', ConnectType.sqlalchemy)
21+
ck = ('ck', '"', '"', ConnectType.sqlalchemy)
22+
dm = ('dm', '"', '"', ConnectType.py_driver)
23+
24+
def __init__(self, type, prefix, suffix, connect_type: ConnectType):
1625
self.type = type
1726
self.prefix = prefix
1827
self.suffix = suffix
28+
self.connect_type = connect_type
1929

2030
@classmethod
2131
def get_db(cls, type):

0 commit comments

Comments
 (0)