22import json
33import os
44import platform
5- import re
65import urllib .parse
76from datetime import datetime , date , time , timedelta
87from decimal import Decimal
1918 import dmPython
2019import pymysql
2120import redshift_connector
22- from sqlalchemy import create_engine , text , Engine , types
21+ from sqlalchemy import create_engine , text , Engine
22+ from sqlalchemy .types import Integer , Float , Numeric , Boolean
2323from sqlalchemy .orm import sessionmaker
2424
2525from apps .datasource .models .datasource import DatasourceConf , CoreDatasource , TableSchema , ColumnSchema
@@ -582,6 +582,19 @@ def convert_value(value, datetime_format='space'):
582582 return value
583583
584584
585+ NUMERIC_BASE_TYPES = (Integer , Numeric , Boolean )
586+
587+ def get_numeric_type_codes (dialect_name ):
588+ """根据数据库方言获取数值类型的 type_code 集合"""
589+ type_codes = {
590+ 'postgresql' : {20 , 21 , 23 , 700 , 701 , 1700 , 16 }, # int8, int2, int4, float4, float8, numeric, bool
591+ 'mysql' : {1 , 2 , 3 , 4 , 5 , 8 , 9 , 16 , 246 }, # tinyint, smallint, int, float, double, bigint, mediumint, bit, decimal
592+ 'mssql' : {38 , 48 , 52 , 56 , 58 , 59 , 60 , 61 , 62 , 104 , 106 , 108 , 122 , 127 }, # SQL Server 类型码
593+ 'oracle' : {2 , 4 , 6 , 8 , 168 }, # NUMBER, FLOAT, BINARY_FLOAT, BINARY_DOUBLE, etc.
594+ 'sqlite' : {1 , 2 , 3 , 4 , 5 }, # SQLite 类型码
595+ }
596+ return type_codes .get (dialect_name , set ())
597+
585598def exec_sql (ds : CoreDatasource | AssistantOutDsSchema , sql : str , origin_column = False ):
586599 while sql .endswith (';' ):
587600 sql = sql [:- 1 ]
@@ -598,24 +611,20 @@ def exec_sql(ds: CoreDatasource | AssistantOutDsSchema, sql: str, origin_column=
598611 columns = result .keys ()._keys if origin_column else [item .lower () for item in result .keys ()._keys ]
599612
600613 fields_info = []
601- for col_info in result .cursor .description :
602- # col_info 是 (name, type_code, display_size, internal_size, precision, scale, null_ok)
603- col_name = col_info [0 ]
604-
605- # 根据 type_code 判断是否为数值类型
606- # psycopg2 的类型 OID 常量
607- is_numeric = col_info [1 ] in (
608- 20 , # int8
609- 21 , # int2
610- 23 , # int4
611- 700 , # float4
612- 701 , # float8
613- 1700 , # numeric
614- 16 , # boolean
615- )
614+
615+ # 获取当前数据库方言
616+ dialect_name = session .bind .dialect .name
617+ numeric_codes = get_numeric_type_codes (dialect_name )
618+
619+ for col_idx , col_name in enumerate (columns ):
620+ try :
621+ type_code = result .cursor .description [col_idx ][1 ]
622+ is_numeric = type_code in numeric_codes
623+ except (IndexError , AttributeError ):
624+ is_numeric = False
616625
617626 fields_info .append ({
618- "name" : col_name if origin_column else col_name . lower () ,
627+ "name" : col_name ,
619628 "is_numeric" : is_numeric
620629 })
621630
0 commit comments