From b389e860f2795972613d1e230549d0a1c7fb2006 Mon Sep 17 00:00:00 2001 From: junjun Date: Fri, 24 Oct 2025 16:00:29 +0800 Subject: [PATCH] feat: add oracle instant client to support oracle version 11 --- backend/apps/datasource/crud/datasource.py | 14 ++++++++---- backend/apps/db/db.py | 26 +++++++++++++++++----- backend/common/core/config.py | 2 ++ 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/backend/apps/datasource/crud/datasource.py b/backend/apps/datasource/crud/datasource.py index c2303776..a6a867e1 100644 --- a/backend/apps/datasource/crud/datasource.py +++ b/backend/apps/datasource/crud/datasource.py @@ -303,10 +303,16 @@ def preview(session: SessionDep, current_user: CurrentUser, id: int, data: Table {where} LIMIT 100""" elif ds.type == "oracle": - sql = f"""SELECT "{'", "'.join(fields)}" FROM "{conf.dbSchema}"."{data.table.table_name}" - {where} - ORDER BY "{fields[0]}" - OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY""" + # sql = f"""SELECT "{'", "'.join(fields)}" FROM "{conf.dbSchema}"."{data.table.table_name}" + # {where} + # ORDER BY "{fields[0]}" + # OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY""" + sql = f"""SELECT * FROM + (SELECT "{'", "'.join(fields)}" FROM "{conf.dbSchema}"."{data.table.table_name}" + {where} + ORDER BY "{fields[0]}") + WHERE ROWNUM <= 100 + """ elif ds.type == "ck": sql = f"""SELECT "{'", "'.join(fields)}" FROM "{data.table.table_name}" {where} diff --git a/backend/apps/db/db.py b/backend/apps/db/db.py index e307ac18..85b28147 100644 --- a/backend/apps/db/db.py +++ b/backend/apps/db/db.py @@ -5,8 +5,10 @@ import urllib.parse from decimal import Decimal from typing import Optional +import oracledb import psycopg2 import pymssql + from apps.db.db_sql import get_table_sql, get_field_sql, get_version_sql from common.error import ParseSQLResultError @@ -27,10 +29,20 @@ from common.core.deps import Trans from common.utils.utils import SQLBotLogUtil, equals_ignore_case from fastapi import HTTPException from apps.db.es_engine import get_es_connect, get_es_index, get_es_fields, get_es_data_by_http +from common.core.config import settings + +try: + oracledb.init_oracle_client( + lib_dir=settings.ORACLE_CLIENT_PATH + ) + SQLBotLogUtil.info("init oracle client success, use thick mode") +except Exception: + SQLBotLogUtil.error("init oracle client failed, use thin mode") def get_uri(ds: CoreDatasource) -> str: - conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration))) if not equals_ignore_case(ds.type, "excel") else get_engine_config() + conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration))) if not equals_ignore_case(ds.type, + "excel") else get_engine_config() return get_uri_from_config(ds.type, conf) @@ -102,7 +114,8 @@ def get_origin_connect(type: str, conf: DatasourceConf): # use sqlalchemy def get_engine(ds: CoreDatasource, timeout: int = 0) -> Engine: - conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration))) if not equals_ignore_case(ds.type, "excel") else get_engine_config() + conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration))) if not equals_ignore_case(ds.type, + "excel") else get_engine_config() if conf.timeout is None: conf.timeout = timeout if timeout > 0: @@ -233,7 +246,8 @@ def get_version(ds: CoreDatasource | AssistantOutDsSchema): conf = None if isinstance(ds, CoreDatasource): conf = DatasourceConf( - **json.loads(aes_decrypt(ds.configuration))) if not equals_ignore_case(ds.type, "excel") else get_engine_config() + **json.loads(aes_decrypt(ds.configuration))) if not equals_ignore_case(ds.type, + "excel") else get_engine_config() if isinstance(ds, AssistantOutDsSchema): conf = DatasourceConf() conf.host = ds.host @@ -319,7 +333,8 @@ def get_schema(ds: CoreDatasource): def get_tables(ds: CoreDatasource): - conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration))) if not equals_ignore_case(ds.type, "excel") else get_engine_config() + conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration))) if not equals_ignore_case(ds.type, + "excel") else get_engine_config() db = DB.get_db(ds.type) sql, sql_param = get_table_sql(ds, conf, get_version(ds)) if db.connect_type == ConnectType.sqlalchemy: @@ -369,7 +384,8 @@ def get_tables(ds: CoreDatasource): def get_fields(ds: CoreDatasource, table_name: str = None): - conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration))) if not equals_ignore_case(ds.type, "excel") else get_engine_config() + conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration))) if not equals_ignore_case(ds.type, + "excel") else get_engine_config() db = DB.get_db(ds.type) sql, p1, p2 = get_field_sql(ds, conf, table_name) if db.connect_type == ConnectType.sqlalchemy: diff --git a/backend/common/core/config.py b/backend/common/core/config.py index bf9d0759..eeec375e 100644 --- a/backend/common/core/config.py +++ b/backend/common/core/config.py @@ -111,5 +111,7 @@ class Settings(BaseSettings): TABLE_EMBEDDING_COUNT: int = 10 DS_EMBEDDING_COUNT: int = 10 + ORACLE_CLIENT_PATH: str = '/opt/sqlbot/db_client/oracle_instant_client' + settings = Settings() # type: ignore