feat: support ClickHouse datasource

This commit is contained in:
junjun
2025-08-14 17:58:01 +08:00
parent e1e482e269
commit f586aec67f
8 changed files with 37 additions and 3 deletions
@@ -293,6 +293,10 @@ def preview(session: SessionDep, current_user: CurrentUser, id: int, data: Table
{where}
ORDER BY "{fields[0]}"
OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY"""
elif ds.type == "ck":
sql = f"""SELECT "{'", "'.join(fields)}" FROM "{data.table.table_name}"
{where}
LIMIT 100"""
return exec_sql(ds, sql)
+1
View File
@@ -10,6 +10,7 @@ class DB(Enum):
pg = ('pg', '"', '"')
excel = ('excel', '"', '"')
oracle = ('oracle', '"', '"')
ck = ('ClickHouse', '"', '"')
def __init__(self, type, prefix, suffix):
self.type = type
+25 -1
View File
@@ -46,6 +46,11 @@ def get_uri_from_config(type: str, conf: DatasourceConf) -> str:
db_url = f"oracle+oracledb://{urllib.parse.quote(conf.username)}:{urllib.parse.quote(conf.password)}@{conf.host}:{conf.port}/{conf.database}?{conf.extraJdbc}"
else:
db_url = f"oracle+oracledb://{urllib.parse.quote(conf.username)}:{urllib.parse.quote(conf.password)}@{conf.host}:{conf.port}/{conf.database}"
elif type == "ck":
if conf.extraJdbc is not None and conf.extraJdbc != '':
db_url = f"clickhouse+http://{urllib.parse.quote(conf.username)}:{urllib.parse.quote(conf.password)}@{conf.host}:{conf.port}/{conf.database}?{conf.extraJdbc}"
else:
db_url = f"clickhouse+http://{urllib.parse.quote(conf.username)}:{urllib.parse.quote(conf.password)}@{conf.host}:{conf.port}/{conf.database}"
else:
raise 'The datasource type not support.'
return db_url
@@ -67,7 +72,7 @@ def get_engine(ds: CoreDatasource, timeout: int = 0) -> Engine:
elif ds.type == 'oracle':
engine = create_engine(get_uri(ds),
pool_timeout=conf.timeout)
else:
else: # mysql, ck
engine = create_engine(get_uri(ds), connect_args={"connect_timeout": conf.timeout}, pool_timeout=conf.timeout)
return engine
@@ -144,6 +149,14 @@ def get_tables(ds: CoreDatasource):
AND c.OWNER = '{conf.dbSchema}'
ORDER BY t.TABLE_NAME
"""
elif ds.type == "ck":
sql = f"""
SELECT name, engine
FROM system.tables
WHERE database = '{conf.database}'
AND engine NOT IN ('Dictionary')
ORDER BY name
"""
with session.execute(text(sql)) as result:
res = result.fetchall()
res_list = [TableSchema(*item) for item in res]
@@ -226,6 +239,17 @@ def get_fields(ds: CoreDatasource, table_name: str = None):
"""
sql2 = f" AND col.TABLE_NAME = '{table_name}'" if table_name is not None and table_name != "" else ""
sql = sql1 + sql2
elif ds.type == "ck":
sql1 = f"""
SELECT
name AS COLUMN_NAME,
type AS DATA_TYPE,
comment AS COLUMN_COMMENT
FROM system.columns
WHERE database = '{conf.database}'
"""
sql2 = f" AND table = '{table_name}'" if table_name is not None and table_name != "" else ""
sql = sql1 + sql2
with session.execute(text(sql)) as result:
res = result.fetchall()
+2 -1
View File
@@ -9,5 +9,6 @@ def db_type_relation() -> Dict:
"sqlServer": "Microsoft SQL Server",
"pg": "PostgreSQL",
"excel": "Excel/CSV",
"oracle": "Oracle"
"oracle": "Oracle",
"ck": "ClickHouse"
}
+1
View File
@@ -43,6 +43,7 @@ dependencies = [
"xlsxwriter>=3.2.5",
"python-calamine>=0.4.0",
"xlrd>=2.0.2",
"clickhouse-sqlalchemy>=0.3.2",
]
[[tool.uv.index]]
name = "default"
+1 -1
View File
@@ -27,7 +27,7 @@ template:
- SQL查询的字段若是函数字段,如 COUNT(),CAST() 等,必须加上别名
- 计算占比,百分比类型字段,保留两位小数,以%结尾。
- 生成SQL时,必须避免关键字冲突。
- 如数据库引擎是 PostgreSQL、Oracle,则在schema、表名、字段名、别名外层加双引号;
- 如数据库引擎是 PostgreSQL、Oracle、ClickHouse,则在schema、表名、字段名、别名外层加双引号;
- 如数据库引擎是 MySQL,则在表名、字段名、别名外层加反引号;
- 如数据库引擎是 Microsoft SQL Server,则在schema、表名、字段名、别名外层加方括号。
- 以PostgreSQL为例,查询Schema为TEST表TABLE下所有数据,则生成的SQL为:
Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

+3
View File
@@ -3,6 +3,7 @@ import excel from '@/assets/datasource/icon_excel.png'
import oracle from '@/assets/datasource/icon_oracle.png'
import pg from '@/assets/datasource/icon_PostgreSQL.png'
import sqlServer from '@/assets/datasource/icon_SQL_Server.png'
import ck from '@/assets/datasource/icon_ck.png'
import { i18n } from '@/i18n'
const t = i18n.global.t
@@ -12,6 +13,7 @@ export const dsType = [
{ label: 'Oracle', value: 'oracle' },
{ label: 'PostgreSQL', value: 'pg' },
{ label: 'SQL Server', value: 'sqlServer' },
{ label: 'ClickHouse', value: 'ck' },
]
export const dsTypeWithImg = [
@@ -20,6 +22,7 @@ export const dsTypeWithImg = [
{ name: 'Oracle', type: 'oracle', img: oracle },
{ name: 'PostgreSQL', type: 'pg', img: pg },
{ name: 'SQL Server', type: 'sqlServer', img: sqlServer },
{ name: 'ClickHouse', type: 'ck', img: ck },
]
export const haveSchema = ['sqlServer', 'pg', 'oracle']