Files
ai-g3sb-backman2.0/backend/db/__pycache__/dbhub_tools.cpython-312.pyc
T

436 lines
52 KiB
Plaintext
Raw Normal View History

2026-04-14 10:28:22 +08:00
Ë
|®Üi~Äãó6—dZddlmZddlZddlZddlZddlZddlmZddl m
Z
m Z ddl m
Z
mZddlmZddlmZdd lmZmZdd
lmZmZmZmZmZdd lmZej<e«Z d;d „Z!e d
Z"e dZ#e$hd£«Z%d<d„Z&d=d„Z'd=d„Z(d>d„Z)d?d„Z*d@d„Z+dAd„Z,dBd„Z-dCd„Z.dDd„Z/dCd„Z0 dEd„Z1dFd„Z2e$hd£«Z3ejhd«Z5dGd„Z6dHd „Z7dId!„Z8dJd"„Z9dJd#„Z: dKd$„Z; dLd%„Z<dMd&„Z= dNd'„Z>d(dd)œ dOd*„Z?d(d+œ dPd,„Z@d(d+œ dQd-„ZAd.d/œ dRd0„ZBd.d/œdSd1„ZC dT dUd2„ZDGd3„d4«ZEeE«ZFdVd5„ZGdWd6„ZHdWd7„ZIdXd8„ZJdYd9„ZKed:k(reK«yy)Zu¯
与 DBHub 对�的数�库工具:search_objects(元数�探索)�execute_sql(SQL 执行,对� execute-sql.ts)�
execute_sql_all(� execute_sql 但�截断行数)�execute_sql_count_only(仅统计行数,�返回明细)。
Text2SQL Validator 使用 ``probe_sql_execution_status`` / ``probe_sql_execution_status_ex`` �库上探针。
- 模�级 ``execute_sql`` / ``execute_sql_all`` / ``execute_sql_count_only`` / ``search_objects``:便�入�,委托给 ``default_dbhub_tools``。
- ``DbHubTools``:�实例化的工具类,方法语义与上述模�函数相�。
- ``default_dbhub_tools``:默认�例实例,与模�级函数共用。
é)Ú annotationsN)ÚDecimal)ÚAnyÚLiteral)ÚinspectÚtext)ÚEngine)ÚSQLAlchemyError)Úallowed_keywords_listÚis_read_only_sql)Ú
ConnectorTypeÚ _get_scannerÚ _TOKEN_PLAINÚsplit_sql_statementsÚstrip_comments_and_strings)Ú
get_enginecóD—tj|«}|�2t|«j«rt|«j«Stj|j ««}|�2t|«j«rt|«j«Sy)u_从环境å�˜é‡�读å�–(与根目录 .env / load_dotenv 一致);键å��大å°�写ä¸�æ•�感。N)ÚosÚgetenvÚstrÚstripÚupper)ÚkeyÚvÚv2s ú>C:\Users\24019\Desktop\backman-camel\backend\db\dbhub_tools.pyÚ_get_optional_strr%sh€ä
� ‰ �#‹€AØ€}œ˜Q›Ÿ™œÜ�1‹v�|‰|‹~ÐÜ �‰�3—9‘9“;Ó €BØ €~œ#˜b›'Ÿ-™-œ/Ü�2‹w�}‰}‹ÐØ ó)ÚschemaÚtableÚcolumnÚ procedureÚfunctionÚindex)ÚnamesÚsummaryÚfull>ÚsysÚmysqlÚpg_toastÚ
pg_catalogÚinformation_schemaÚperformance_schemacó*—g}|D]T}|dk(r|jd«Œ|dk(r|jd«Œ1|jtj|««ŒVtjddj |«zdztj
«S)u_SQL LIKE → regex,与 DBHub likePatternToRegex 一致(% / _,其余字符 re.escape)。Ú%z.*Ú_Ú.Ú^ÚÚ$)ÚappendÚreÚescapeÚcompileÚjoinÚ
IGNORECASE)ÚpatternÚpartsÚcs rÚ_like_pattern_to_regexr>?st€à€EÛ
ˆØ �Š8Ø �L‰L˜Õ Ø
�#ŠXØ �L‰L˜Õ à �L‰LœŸ™ 1›Õ &ð
ô �:‰:�c˜BŸG™G E›NÑ*¨SÑ0´"·-±-Ó @Ð@rcód—|j«jdd«dj«S)Nr1ééÿÿÿÿ)rÚrsplit)Únames rÚ_bare_table_namerDLs)€Ø �:‰:‹<× Ñ ˜s AÓ & rÑ *× 0Ñ 0Ó 2Ð2rcóŒ—|j«}t|«dk\r%|ddk(r|ddk(r|ddjdd«S|S)uJ去掉首尾空白;若整段为 [Name] å½¢å¼�则去括å�·ï¼ˆå�•层)。érÚ[rAÚ]r@z]])rÚlenÚreplace)rCÚts rÚ_normalize_user_object_namerLPsH€à �
‰
‹ €AÜ
ˆ1ƒv�‚{�q˜‘t˜s’{ q¨¡u°¢|Ø��2ˆw�‰˜t SÓ)Ð)Ø €Hrcó0—t|«}|s|j«S|j«}|j|jfD]>} ||¬«D]/}t t
|««}|j«|k(sŒ+|ccSŒ@|S#t$rYŒNwxYw)u¬
将用户输入的表/视图�解�为与 SQLAlchemy inspect 一致��在 get_columns/get_indexes 中使用的�称。
SQL Server 等库对标识符大�写��感,但�射时传入与系统目录�一致的大�写�能导致 get_columns 返回空;
视图�在 get_table_names 中,仅传表�会�匹�。本函数在指定 schema 下对表�与视图���区分大�写对�。
©r)rLrÚlowerÚget_table_namesÚget_view_namesrDrÚ Exception)ÚinsprÚ
user_tableÚwantrÚlisterÚrawÚbares rÚ _resolve_table_or_view_bare_namerYXs–€ô ' zÓ 2€DÙ Ø×ÑÓ!Ð!Ø
�*‰*‹,€CØ×'Ñ'¨×)<Ñ)<Ó=ˆð Ù V×,�Ü'¬¨C«Ó1�Ø—:‘:“< 3Ó&Ø”Kñ-ð>ð €Køôò Ù ð úsÁ
3B Á>B ÂB  BÂBcó`—|D�cgc]}|sŒ|j«tvsŒ|‘Œ c}Scc}w©N)rOÚ
_SKIP_SCHEMAS)rWÚss rÚ_filter_schemasr^ns)€ÙÓ C‘s�!ša A§G¡G£I´]Ò$BŠA�sÑ CÐCùÒ Cs …+�+¤+có„—|jj}|j|«}|r|j|«›d|›�S|S)Nr1)ÚdialectÚidentifier_preparerÚquoteÚ quote_schema)ÚenginerÚ
bare_tableÚprepÚtqs rÚ_qualified_table_sqlrhrsD€Ø �>‰>× -Ñ -€DØ
�‰�JÓ €BÙ
Ø×#Ñ# FÓ+Ð,¨A¨b¨TÐ2Ð2Ø
€Ircó—t|||«} |j«5}|jtd|›�««}|j «}|€
ddd«yt |d«cddd«S#1swYyxYw#t $rYywxYw)NzSELECT COUNT(*) AS c FROM r)rhÚconnectÚexecuterÚfetchoneÚintrR)rdrreÚqÚconnÚrÚrows rÚ_table_row_countrrzsƒ€Ü˜V V¨ZÓ8€AðØ
�^‰^Ô
 Ø— ‘ œTÐ$>¸q¸cÐ"BÓCÓDˆAØ—*‘*“,ˆC؈{Ø÷ Ð
ô
�s˜1‘v“;÷ ×
Ò
ûô òÙðús:�A<Ÿ1A0ÁA<Á
A0Á& A<Á0A9Á5A<Á9A<Á< BÂBcó–— |j||¬«}|jd«xsg}td„|D««S#t$rYywxYw)NrNÚconstrained_columnsc3ó2K—|]}t|«–—Œy­wr[)r)Ú.0r=s rÚ <genexpr>z_pk_columns.<locals>.<genexpr>‹sèø€Ð*¡T ”S˜—V¡Tùs‚©)Úget_pk_constraintÚgetÚtuplerR)rSrrXÚpkÚcolss rÚ _pk_columnsr~‡sS€ðØ
×
#Ñ
# D°Ð
#Ó
8ˆØ�v‰vÐ+Ó,Ò2°ˆÜÑ*¡TÓ*Ó*Ð*øÜ òÙðús‚9<¼ AÁAcó˜—t|||«} t|j||¬««}g}|D]‡}t|j d«xsg«}t |j d««}t |«xrt
|«|k(} |jt|j d«xsd«||| dœ«Œ‰|S#t$rgcYSwxYw)NrNÚ column_namesÚuniquerCr3)rCÚcolumnsr�Úprimary) r~ÚlistÚ get_indexesrRrzÚboolr{r5r)
rSrrXÚpk_colsÚraw_idxÚoutÚidxr}r�rƒs
rÚ _index_dictsr‹�s΀ܘ$ ¨Ó-€GðÜ�t×'Ñ'¨°VÐ'Ó<Ó=ˆð!#€CÛˆÜ�C—G‘G˜NÓ+Ò1¨rÓ2ˆÜ�c—g‘g˜hÓ'Ó(ˆÜ�w“-Ò:¤E¨$£K°7Ñ$:ˆØ �
‰
ä˜CŸG™G F›OÒ1¨rÓ2ØØ Ø"ñ 
õ
ð ð €Jøô òØŠ ðús�B;Â; C ÃC cóè— |j||¬«}t|t«r)|jd«xsdj «}|r|SdS y#t
t tf$rYyt$rYywxYw)u;获å�–表注释,若ä¸�支æŒ�或无注释则返回 None。rNrr3N) Úget_table_commentÚ
isinstanceÚdictrzrÚNotImplementedErrorÚAttributeErrorÚ TypeErrorrR)rSrrXÚtcrs rÚ_table_commentr”¦sˆ€ð
Ø
×
#Ñ
# D°Ð
#Ó
8ˆÜ �bœ$Ô Ø—F‘F˜6“NÒ( b×/Ñ/Ó1ˆDÙ�4Ð ) TÐ )ð ð øô
¤´Ð ;ò
Ø ð ô ò
Ø Ø ð
ús‚A AÁ AÁA1Á&A1Á0A1cóˆ— t|j||¬««}g}|D�] }t|t«sŒt |j
d«xsd«j«}|sŒD|j
d«}|�t |«j«nd}|j
d«} | duxs%t| t
«xr| j«dk(}
|||
rdnd|j
d «d
œ} |j
d «} | � t | «j«}
|
r|
| d <|j| «�Œ|S#t$rgcYSwxYw)
NrNrCr3ÚtypeÚnullableTÚYESÚNOÚdefault)Ú column_nameÚ data_typeÚ is_nullableÚcolumn_defaultÚcommentÚ description)
r„Ú get_columnsrRrŽr�rrzrrr5)rSrrXr}r‰r=ÚfnameÚftypeÚdtyper—Únull_bÚentryrŸÚ comment_strs rÚ
_column_dictsr¨´s?€ðÜ�D×$Ñ$ T°&Ð$Ó9Ó:ˆð!#€CÜ
ˆÜ˜!œTÔ"Ø Ü�A—E‘E˜&“MÒ' RÓ(×.Ñ.Ó0ˆÙØ Ø—‘�f“
ˆØ&+Ð&7”�E“
× Ñ Ô"¸RˆØ—5‘5˜Ó$ˆØ˜TÐ!Ò^¤j°¼3Ó&?Ò&]ÀHÇNÁNÓDTÐX]ÑD]ˆà ØÙ$*™5°ØŸe™e IÓ.ñ !
ˆð—%‘%˜ Ó"ˆØ Рܘg›,×,Ñ,Ó.ˆKÙØ'2��mÑ$Ø �
‰
�5Öð-ð. €Jøô5 òØŠ ðús‚D3Ä3 EÅEc
ó˜—g}|dvr|Sd}i}|r
|dz
}||d<|r
|dz
}||d<|j«5}|jt|«|«D]O}|d} |jt |d«t |d «t |d
«| €d n
t | «d d f«ŒQ d d d «|d vrý|rû d
}
i} |r
|
dz
}
|| d<|r
|
dz
}
|| d<i} jt|
«| «D]k}t |d«t |d «f}
|d
rt |d
«j «nd }|drt |d«j «nd }||f| |
<Œmg}|D]H\}}}} }}||f}
|
| vr | |
\}}|j|||| ||f«Œ2|j|||| d d f«ŒJ|}|S|S#1swY�Œ
xYw#t $rY|SwxYw)u
返回 (schema, name, routine_type, definition_or_none, language_or_none, return_type_or_none)。
routine_sql_type: 'PROCEDURE' | 'FUNCTION' | None(两者都�)
注�:INFORMATION_SCHEMA.ROUTINES 在��数�库中包�的字段��:
- SQL Server: 有 EXTERNAL_LANGUAGE(但通常为 NULL),无 RETURN_TYPE
- MySQL/MariaDB: 有 EXTERNAL_LANGUAGE�DTD_IDENTIFIER(返回类型)
- PostgreSQL: INFORMATION_SCHEMA 中存储过程支�有�,通常需�通过 pg_proc 查询
)ÚmssqlÚ
postgresqlr)Úmariadbz’
SELECT ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES
WHERE 1=1
z AND ROUTINE_SCHEMA = :schÚschz AND ROUTINE_TYPE = :rtÚrtérr@rFN)r)r¬z³
SELECT ROUTINE_SCHEMA, ROUTINE_NAME, EXTERNAL_LANGUAGE, DTD_IDENTIFIER
FROM INFORMATION_SCHEMA.ROUTINES
WHERE 1=1
)rjrkrr5rrrR)rdr`Ú
schema_filterÚroutine_sql_typeÚrowsÚsqlÚparamsrorpÚdefnÚ extra_sqlÚ extra_paramsÚ extra_maprÚlangÚret_typeÚ updated_rowsr­rCÚrtyper0s rÚ_fetch_routinesr½ÔsE€ð LN€DØÐAÑA؈ ð €Cð
 €FÙØ Ð+Ñ+ˆØ%ˆˆu‰
ÙØ Ð(Ñ(ˆØ'ˆˆt‰ à �‰Ô ˜TØ—‘œd 3›i¨Ö0ˆAØ�Q‘4ˆDØ �K‰K䘘!™“Iܘ˜!™“Iܘ˜!™“IØ ˜L‘D¬c°$«iØØð
õ
ñ1÷
ðÐ&Ñ&©4ð! ðˆIð
,.ˆLÙØÐ9Ñ9� Ø&3� ˜UÑ#ÙØÐ6Ñ6� Ø%5� ˜TÑ"àNPˆIØ—\‘\¤$ y£/°<Ö@�ܘ1˜Q™4“y¤# a¨¡d£)Ð,�Ø,-¨aªD”s˜1˜Q™4“y—‘Ô(°d�Ø01°!²œ3˜q ™t›9Ÿ?™?Ô,¸$�Ø"&¨Ð!1� ˜#’ð Að\^ˆLÛ04Ñ,��T˜5 $¨¨1ؘD�k�ؘ)Ñ#Ø%.¨s¡^‘N�D˜(Ø ×'Ñ'¨¨d°E¸4ÀÀxÐ(PÕQà ×'Ñ'¨¨d°E¸4ÀÀtÐ(LÕMð
15ð ˆDð
€Kˆ4€K÷g
Ñ ûô^ò à à €Kð  úsµA.F/Â3C8F<Æ/F9Æ< G ÇG có6—ddddddœ}|j|d«S)už
将 SQLAlchemy dialect.name 映射到 DBHub ConnectorType。
未知方言按 postgres 规则��读校验(与 DBHub 移�约定一致)。
Úpostgresr)r¬ÚsqliteÚ sqlserver)r«r)r¬rÀrª)rz)Ú dialect_nameÚms rÚsqlalchemy_dialect_to_connectorrÄ,s-€ð !ØØØØñ #€Að
�5‰5�˜zÓ *Ð*r>ÚwithÚselectÚexplainz‘(?is)^(?:distinct\s+)?(?:count|sum|avg|min|max|stdev|stdevp|string_agg|group_concat|variance|var_pop|var_samp|stddev|stddev_pop|stddev_samp)\s*\(cób—t||«dk(ryt|«}t|«}d}d}d}d}d}||krú|||«} | dtk7r| d}Œ |dk(rJt j
d|||«}
|
r)d}||
j
«z}||
j
«z
}Œi|d z
}Œo|dk(rLt j
d
|||«} | r1|||} t j
d | j««ry|d z| fS||}
|
d k(r|d z
}n$|
d
k(rtd|d z
«}n|
dk(r
|dk(r|d z
}|d z
}||krŒúy)uÕ
定�最外层 ``SELECT`` 与深度 0 上首个 ``FROM`` 之间的选择列表,返回 (列数, 列表原文断片)。
``WITH`` 开头�``SELECT *``�或无法�对到 ``FROM`` 时返回 None。
rÅNrÚLEADINGr–Úendz(?is)select\s+ÚIN_LISTr@z
(?is)\bfrom\bz(?is)^\s*\*\s*$Ú(Ú)Ú,) Ú_first_sql_keywordrrIrr6ÚmatchrÊrÚmax)r³Ú connectorÚscanÚnÚiÚ
list_parenÚ
col_commasÚstateÚ
list_startÚtokrÃÚmfÚfragr=s rÚ_parse_top_level_select_listrÝCsq€ô
˜#˜yÓ)¨VÒ3ØÜ ˜ Ó "€DÜ ˆC‹€AØ €AØ€JØ€JØ+4€EØ€JØ
ˆaŠ%Ù�3˜‹lˆØ ˆv‰;œ,Ò &Ø�E‘
ˆAØ Ø �IÒ Ü—‘Ð*¨C°°!¨HÓ5ˆAÙØ!�Ø §¡£™[�
Ø�Q—U‘U“W‘ �ØØ
�‰FˆAØ Ø ˜Š?Ü—‘Ð*¨C°°!¨HÓ5ˆBÙØ˜: aÐ(�Ü—8‘8Ð.°·
±
³ Ô=ØØ" Q™¨Ð-Ð-Ø �‰FˆØ �Š8Ø ˜!‰O‰JØ
�#ŠXܘQ 
¨Q¡Ó/‰JØ
�#ŠX˜*¨š/Ø ˜!‰OˆJØ ˆQ‰ˆð9 ˆa‹%ð: rcó—t|«}t|«}d}d}||krk|||«}|dtk7r|d}Œ |dk(rtjd|||«}|ry||}|dk(r|dz
}n|dk(rt d|dz
«}|dz
}||krŒky )
Nrr–rÊz(?is)\bgroup\s+by\bTrÌr@rÍF)rrIrr6rÐrÑ) r³rÒrÓrÔrÕÚdepthrÚrÃr=s rÚ_has_top_level_group_byràqs´€Ü ˜ Ó "€DÜ ˆC‹€AØ €AØ
€EØ
ˆaŠ%Ù�3˜‹lˆØ ˆv‰;œ,Ò &Ø�E‘
ˆAØ Ø �AŠ:Ü—‘Ð/°°Q°q°Ó:ˆAÙØØ �‰FˆØ �Š8Ø �Q‰J‰EØ
�#ŠXܘ˜5 1™9Ó%ˆEØ ˆQ‰ˆð ˆa‹%ð rcóÞ—t||«}|€y|\}}|dk7ryt||«ry|j«}|rtjd|«ryt t j |««S)u‹å�•列ã€�æ—  GROUP BYã€�且选择列表以常è§�è�šå�ˆå‡½æ•°å¼€å¤´æ—¶ï¼Œç»“果集为标é‡�,宜直接执行内层而é�ž COUNT(*) 包裹。Fr@z (?is)^\*\s*$)rÝràrr6rÐr†Ú_AGGREGATE_SCALAR_PREFIX)ÚinnerrÒÚparsedÚncolsrÜÚfss rÚ_is_aggregate_scalar_fast_pathrçˆsk€ä
)¨%°Ó
;€FØ
€~ØØ�K€Eˆ4Ø �‚zØÜ˜u iÔ0ØØ
�‰‹€BÙ
”—‘˜/¨2Ô.ØÜ Ô(×.Ñ.¨rÓ2Ó 3Ð3rcó¾—|dvr|St|«}t|«}d}d}d}||kr€|||«}|dtk7r|d}Œ |dk(r1tjd|||«}|r|}||j «z
}ŒV||} | dk(r|dz
}n| d k(rt
d|dz
«}|dz
}||krŒ€|dkr|S|d
|j«jd «j«S) uI
SQL Server / MySQL / MariaDB:派生表内 ``ORDER BY`` 若无 TOP/OFFSET/LIMIT 会报语法错误。
在 COUNT �查询包装�去掉最外层(括�深度为 0)最�一次出现的 ``ORDER BY`` �其�内容;
�改�行数统计语义。注释与字符串内的括�/关键字��与解�。
©rÁr)r¬rrAr–rÊz(?is)order\s+by\brÌr@rÍNÚ;)rrIrr6rÐrÊrÑÚrstrip)
r³rÒrÓrÔrÕrßÚlast_order_by_startrÚrÃr=s
rÚ_strip_outer_trailing_order_byrí˜s€ð Ð9Ñ9؈
Ü ˜ Ó "€DÜ ˆC‹€AØ €AØ
€EØÐØ
ˆaŠ%Ù�3˜‹lˆØ ˆv‰;œ,Ò &Ø�E‘
ˆAØ à �AŠ:Ü—‘Ð-¨s°1°Q¨xÓ8ˆAÙØ&'Ð#Ø�Q—U‘U“W‘ �ØØ �‰FˆØ �Š8Ø �Q‰J‰EØ
�#ŠXܘ˜5 1™9Ó%ˆEØ ˆQ‰ˆð# ˆa‹%ð$˜QÒØˆ
Ø Ð#Ð#Ð $× +Ñ +Ó -× 4Ñ 4°SÓ 9× @Ñ @Ó BÐBrcó¬—t||«}|j«j«}tjd|«}|r|j d«SdS)uK剥离注释与字符串字é�¢é‡�å�Žï¼Œå�–首个é�žç©ºç™½è¯�(å°�写)。z\S+rr3)rrrOr6ÚsearchÚgroup)r³rÒÚcleanedrÃs rrÏrϼsG€ä(¨¨iÓ8€GØ�m‰m‹o×#Ñ#Ó%€GÜ
� ‰ �&˜'Ó"€AÙˆ1�7‰7�1‹:Ð" Ð"rcó—|j«}|s td«‚t||«}d|›d�}|�-|dvr)djd„t |«D««}|›d|›d�S|S) NõSQL ä¸�能为空z&SELECT COUNT(*) AS __dbhub_cnt FROM (
z
) AS __dbhub_subqréú, c3ó&K—|] }d|›�–—Œ y­w)Ú __dbhub_cNrx)rvÚks rrwz%_sql_wrapped_count.<locals>.<genexpr>Ósèø€Ð@±<¨a˜I a Sœ/±<ùs‚z (rÍ)rÚ
ValueErrorrír9Úrange)Ú inner_sqlrÒrårãÚcorer%s rÚ_sql_wrapped_countrüÄs‚€ð
�O‰OÓ €EÙ ÜÐ+Ó,Ð,Ü *¨5°)Ó <€Eà1Ø ˆ'ðð ð ð

ИYÐ*KÑKØ— ‘ Ñ@´5¸´<Ó@Ó@ˆØ��r˜%˜ Ð"Ð"Ø €Krcó¸—|j«5}t|«D�]%\}}|j«}|t|«dz
kr7|j t |««}|j r|j«Œ_|s td«‚t||«}|tv�r\t|j«|«} t| |«r||j t | ««}|j«}
|
�|
d€
ddd«y|
d} t| t«rt!| «ccddd«St!| «ccddd«St#| |«} | €K|j t | ««}|j s
ddd«yd}
|D]}|
dz
}
Œ |
ccddd«S| \}}t%| ||«}|j t |««}|j«}
|
€
ddd«yt!|
d«ccddd«S|j t |««}|j s
ddd«yd}
|D]}|
dz
}
Œ |
ccddd«S ddd«y#1swYyxYw)uÊ
顺�执行多�语�;对最�一�:优先用 COUNT �查询��标�(select/with/explain),
�则�次执行�在 Python 侧�行计数(�组装 rows 明细)。
r@õ
SQL 为空Nr)rjÚ enumeraterrIrkrÚ returns_rowsÚfetchallrørÏÚ_COUNT_WRAP_FIRST_WORDSrírçrlrŽrrmrÝrü)rdÚ
statementsrÒrorÕÚstmtr]rpÚfirstrãrqÚcellrärÔr0råÚ_fragÚwrappeds rÚ"_execute_sql_statements_count_onlyr Øs-€ð
�‰Ô ˜TÜ  ×,‰GˆAˆtØ—
‘
“ ˆAØ”3�z“? QÑ&Ò&Ø—L‘L¤ a£Ó)�Ø—>’>Ø—J‘J”LØÙÜ  Ó.Ð.Ü& q¨)Ó4ˆEØÔ/Ò/Ü6°q·w±w³yÀ)ÓL�Ü1°%¸ÔCØŸ ™ ¤T¨%£[Ó1�AØŸ*™*›,�CØ�{ c¨!¡f nØ ÷#
Ð ð$˜q™6�DÜ! $¬Ô0Ü" 4›yÑ(÷)
Ñ ô*˜t›9Ñ$÷+
Ñ ô,6°e¸YÓG�Ø�>ØŸ ™ ¤T¨%£[Ó1�AØŸ>š>Ø ÷5
Ð ð6�AؘۘQ™™ðà‘H÷=
Ñ ð> &‘ ��uÜ,¨U°I¸uÓE�Ø—L‘L¤ g£Ó/�Ø—j‘j“l�Ø�;Ø÷I
Ð ôJ˜3˜q™6“{Ñ"÷K
Ñ ðL— ‘ œT !›WÓ%ˆAØ—>’>Ø÷Q
Ð ðRˆAÛ�Ø�Q‘‘ðà‰H÷Y
Ñ Ù,÷
× Ñ úsB‘C%IÃ?!IÄ* IÅ5IÅ>IÆ?IÇ!IÇ:'IÈ*IÉIÉIcóü—t|t«r t|«St|ttf«rt|«j dd¬«St
|d«r |j«S|S#t$r|cYSwxYw)Nzutf-8rJ)ÚerrorsÚ isoformat) rŽrrÚbytesÚ bytearrayÚdecodeÚhasattrr rR)Úvals rÚ_serialize_sql_cellrsv€Ü�#”wÔÜ�3‹xˆÜ�#œœyÐ)Ô*Ü�S‹z× Ñ  °Ð Ó;Ð;܈s�KÔ ð Ø—=‘=“?Ð "ð €Jøôò ØŠJð úsÁA-Á- A;Á:A;có¼—g}g}d}|j«5}d}t|«D�]\}} | j«}
|jt |
««}|t |«dz
kr|j r|j«Œ_|j sg}g}d}n­t|j««}|€|j«} d}n<tdt|««} |j| dz«}
t |
«| kD}|
d| } g}| D]9}i}t|«D]\}}t||«||<Œ|j|«Œ;�Œddd«|||fS#1swYŒxYw)u•顺åº�执行多æ�¡è¯­å�¥ï¼Œä»…返回最å�Žä¸€æ�¡æœ‰ç»“果集语å�¥çš„列与行。``max_rows`` 为 None 时对最å�Žä¸€æ�¡ ``fetchall``,ä¸�截断。FNr@)rjrÿrrkrrIrrr„ÚkeysrÑrmÚ fetchmanyrr5)rdrÚmax_rowsÚ last_colsÚ last_rowsÚ truncatedroÚresultrÕrr]Ú rows_dataÚmrÚfetchedrqÚrow_mapÚjÚcols rÚ_execute_sql_statementsr!s^€ð€IØ)+€IØ€IØ �‰Ô ˜TØˆÜ  ×,‰GˆAˆtØ—
‘
“ ˆAØ—\‘\¤$ q£'Ó*ˆFØ”3�z“? QÑ&Ò&Ø×&Ò&Ø—O‘OÔ%ØØ×&Ò&Ø� Ø� Ø!� ÙܘVŸ[™[›]Ó+ˆIØÐØ"ŸO™OÓ-� Ø!‘ 䘜C ›MÓ*�Ø ×*Ñ*¨2°©6Ó2�Ü ›L¨2Ñ-� Ø# C R˜L� ؈IÛ �Ø-/�Ü'¨ Ö2‘F�A�sÜ#6°s¸1±vÓ#>�G˜C’Lð3à× Ñ  Õ)ò !ð--÷
ð: �i Ð *Ð*÷;
Ð ús —D.EÅET©Úreadonlyrc ó*—|xsdj«}|s td«‚td«xsdj«}|s td«‚t«}t |j
j «}t||«}|s td«‚|r?|D]:}t||«rŒdjt|««xsd} td| ›�«‚|�|nttd
«xsd «}
td td t|
«««}
tjd
t!|«›d|›d|
›�« t#|||
¬«\} } }
t!| «}| |d| |
dœS#t$$r2}tj'd|›�«tt)|««|‚d }~wwxYw)u
在已�置的业务库上执行 SQL(�多语�,分�分隔)。
:param sql: 待执行 SQL 字符串。多�语�用分�分隔;
:param readonly: 是��用�读校验,默认 True。为 True 时,任一�语��符� G3SB �许的首关键字
(如 select�with�explain 等,�方言而异)或��更类关键字则抛出 ValueError。
为 False 时��上述校验,�执行 DML/DDL(风险自负,勿用于��信输入)。
:param max_rows: 对「最�一�返回结果集的语��最多�多少行;None 时使用�置项 sql_max_rows,
并在实现侧夹紧到 1~10000。��的语�若产生结果集会被消费掉但�返回。
:return: 字典,� rows�count�source_id(固定 ``default``)�columns�truncated。
最�一�语�无结果集时 rows�columns 为空,count 为 0。未�置 database_url�SQL 为空或执行失败时
抛出 ValueError(或包装�的底层异常信�)。
r3róÚ database_urlõdatabase_url 未é…�ç½®rþrôÚnoneúJRead-only mode is enabled. Only the following SQL operations are allowed: NÚ sql_max_rowsi'r@u_execute_sql 执行语å�¥æ•°=ú
readonly=z
max_rows=©ru_execute_sql 执行失败: rš©r²ÚcountÚ source_idr‚r)rrørrrÄr`rCrr r9r rmrÑÚminÚlogÚinforIr!rRÚerrorr)r³r#rrWÚurlrdrÒrÚstÚkwrr}r²rÚer-s rÚ _execute_sqlr7Gsž€ð$ Š9�"×
Ñ
Ó
€CÙ ÜÐ+Ó,Ð,ä ˜^Ó ,Ò 2°×
9Ñ
9Ó
;€CÙ ÜÐ1Ó2Ð2ä
‹\€FÜ/°·±×0CÑ0CÓD€IÜ% c¨9Ó5€Já ܘÓ&Ð&áÛˆBÜ# B¨ Õ2Ø—Y‘YÔ4°YÓ?Ó@ÒJÀF�Ü Ø`ÐacÐ`dÐeóðððÐ)‰¬sÔ3DÀ^Ó3TÒ3]ÐX]Ó/^€BÜ ˆQ”�Eœ3˜r›7Ó#Ó $€Bä‡H�HÐ,¬S°«_Ð,=¸ZÈÀzÐQ[Ð\^Ð[_Ð
`Ôað(Ü 7¸À
ÐUWÔ Xшˆd�Iô
�‹I€EàØØØØñ  ðøô ò(Ü � ‰ Ð/°¨sÐ3Ô4Üœ˜Q›Ó  aÐ'ûð(úsÄ2EÅ FÅ -F
Æ
F©r#có®—|xsdj«}|s td«‚td«xsdj«}|s td«‚t«}t |j
j «}t||«}|s td«‚|r?|D]:}t||«rŒdjt|««xsd}td|›�«‚tjd t|«›d
|›�« t||d ¬ «\} }
} t|
«}
|
|
d| | dœS#t$r2} tj!d
| ›�«tt#| ««| ‚d } ~ wwxYw)uõ
与 ``_execute_sql`` 相�校验与返回结构,但对最�一�有结果集的语��� ``max_rows`` 截断,全部 ``fetchall``。
超大结果集会�用大�内存,仅用于�信 SQL / 已自行 LIMIT 的场景。
r3rór%r&rþrôr'r(u!_execute_sql_all 执行语å�¥æ•°=r*Nr+u_execute_sql_all 执行失败: ršr,)rrørrrÄr`rCrr r9r r0r1rIr!rRr2r)r³r#rWr3rdrÒrr4r5r}r²rr6r-s rÚ_execute_sql_allr:…sa€ð Š9�"×
Ñ
Ó
€CÙ ÜÐ+Ó,Ð,ä ˜^Ó ,Ò 2°×
9Ñ
9Ó
;€CÙ ÜÐ1Ó2Ð2ä
‹\€FÜ/°·±×0CÑ0CÓD€IÜ% c¨9Ó5€Já ܘÓ&Ð&áÛˆBÜ# B¨ Õ2Ø—Y‘YÔ4°YÓ?Ó@ÒJÀF�Ü Ø`ÐacÐ`dÐeóððô‡H�HÐ0´°Z³Ð0AÀÈHÈ:Ð
VÔWð(Ü 7¸À
ÐUYÔ Zшˆd�Iô
�‹I€EàØØØØñ  ðøô ò(Ü � ‰ Ð3°A°3Ð7Ô8Üœ˜Q›Ó  aÐ'ûð(úsÃ4DÄ EÄ"-EÅEcón—|xsdj«}|s td«‚td«xsdj«}|s td«‚t«}t |j
j «}t||«}|s td«‚|r?|D]:}t||«rŒdjt|««xsd}td|›�«‚tjd t|«›d
|›�« t|||«} d | iS#t$r&}
tj!d |
›�«d d
icYd}
~
Sd}
~
wwxYw)uµ
在已�置的业务库上执行 SQL,仅返回「最�一�有结果集语��的行数,�返回�元格明细。
对以 select / with / explain 开头(注释剥离�)的最�一�语�:若已为�列常���(如 ``count(1)``)且无 ``GROUP BY``,
则直接执行该语�并�标�,�� ``COUNT(*)`` 外包一层�得到 1 行。�则在库侧用 ``SELECT COUNT(*) FROM ( ... )``;
对 SQL Server / MySQL / MariaDB 会为派生表补上 ``(__dbhub_c0, ...)`` 列�(��匿�列 8155 等),并在包装�去掉
最外层无�义的 ``ORDER BY``。无法解�选择列表时(如 ``WITH``�``SELECT *``)改为拉全结果在 Python 侧�行计数。
其它�读语�(如部分 show/pragma)��次执行��行计数,�组装为 dict。
多�语�用分�分隔时,��的语�照常执行并消费结果集;仅对最�一�给出计数。
最�一�无结果集时 count 为 0。进入执行阶段�若任一步失败(�语法����连接中断等),返回 ``{"count": -1}``;
SQL 为空�未�置 ``database_url``��读校验�通过�抛 ``ValueError``。
r3rór%r&rþrôr'r(u(_execute_sql_count_only 执行语å�¥æ•°=r*u&_execute_sql_count_only 执行失败: r-rAN)rrørrrÄr`rCrr r9r r0r1rIr rRr2) r³r#rWr3rdrÒrr4r5rÔr6s rÚ_execute_sql_count_onlyr<·s<€ð$ Š9�"×
Ñ
Ó
€CÙ ÜÐ+Ó,Ð,ä ˜^Ó ,Ò 2°×
9Ñ
9Ó
;€CÙ ÜÐ1Ó2Ð2ä
‹\€FÜ/°·±×0CÑ0CÓD€IÜ% c¨9Ó5€Já ܘÓ&Ð&áÛˆBÜ# B¨ Õ2Ø—Y‘YÔ4°YÓ?Ó@ÒJÀF�Ü Ø`ÐacÐ`dÐeóððô‡H�HÐ7¼¸J»Ð7HÈ
ÐS[ÐR\Ð
]Ô^ðÜ .¨v°zÀ9Ó Mˆð
�Qˆ<Ðøô òÜ � ‰ Ð:¸1¸#Ð>Ô?ؘˆ}ÕûðúsÃ4
DÄ D4ÄD/Ä)D4Ä/D4r@r+cóZ—td«xsdj«}|sy t|d|¬«}t|jd
«xsg«}t|«d kDry y
#t$rC}tj d|›�«t
|«j«xsd}d|fcYd }~Sd }~wwxYw)uQ
在已�置的业务库上对 SQL ��读试执行,返回状��与失败时的错误摘�。
Returns:
二元组 ``(status, error_message)``:
- ``(None, None)``:未�置 ``database_url``,跳过探针。
- ``(1, None)``:执行�功,且**至少返回一行数�**(与「有列无行�的 SELECT 区分)。
- ``(0, None)``:执行�功,但**数�行数为 0**(�有列�而无行,或无�空结果集)。
- ``(-1, msg)``:执行失败;``msg`` 为异常信�摘�(便于生�阶段�试)。
r%r3)NNTr"u)probe_sql_execution_status 执行失败: z
unknown errorrANr²r)r@N)rN)
rrr7rRr0Úwarningrr„rzrI)r³rr3r‰r6Údetailr²s rÚprobe_sql_execution_status_exr@ës£€ô ˜^Ó ,Ò 2°×
9Ñ
9Ó
;€CÙ Øðܘ3¨¸ÔAˆô
�—‘˜“Ò% 2Ó &€DÜ
ˆ4ƒy�1‚}ØØ øô òÜ � ‰ Ð?À¸sÐCÔDÜ�Q“—‘“Ò2 ?ˆØ�6ˆzÕûðús¢AÁ B*Á'8B%ÂB*Â%B*có&—t||¬«\}}|S)uå
在已�置的业务库上对 SQL ��读试执行,返回紧凑状��(用于 Validator 探针)。
语义与 :func:`probe_sql_execution_status_ex` 的首个返回值一致;失败细节请用 ``_ex``。
r+)r@)r³rÚstatusr0s rÚprobe_sql_execution_statusrCs€ô .¨c¸HÔE�I€FˆAØ €Mrcó@
—|r
|s td«‚|r|dvrtd|›d�«‚tdtdt|«««}|�|nd}t |«}t d «xsd
j
«} | s td «‚ t«}
t|
«} t| j««}
t!|
«}|r.||
vr&dj#|
«xsd}td|›d|›�«‚|g}n|r|ndg}|
j$j&}g}|dk(r“|r|n|
}|D�cgc]}|j)|«sŒ|‘Œ}}|D]e}t+|«|k\r�nO|dk(r|j-d|i«Œ- t| j/|¬««}|j-|t+|«dœ«Œg�nù|dk(�rs|D�]k}t+|«|k\r�nÜ t| j/|¬««}|D�]5}t+|«|k\rŒGt1t|««}|j)|«sŒ:|dk(r|j-||dœ«ŒT|dk(rPt3| ||«}t5|
||«}t7| ||«}||t+|«|dœ}|r||d<|j-|«Œ©t3| ||«}t9| ||«}t5|
||«}t7| ||«}||t+|«||D�cgc]%}|d|d|ddk(|d d!œd"|vrd"|d"ini¥‘Œ'c}|d#œ} |r|| d<|j-| «�Œ8�Œn�n€|dv�rÑ|D�]Ê}t+|«|k\r�nd |rt;| ||«g}!n1| j/|¬«D�"cgc]}"t1t|"««‘Œ}!}"|!D�]m}t+|«|k\rŒnt1t|««}|d$k(r�t3| ||«}|D]z}t+|«|k\rŒO|j)|d«sŒ(|dk(r|j-|d||d%œ«ŒF|d|||d|ddk(|d d&œ}#d"|vr|d"|#d"<|j-|#«Œ|Œºt9| ||«}|D]¢}$t+|«|k\rŒÜt|$j=d«xsd
«}%|j)|%«sŒC|dk(r|j-|%||d%œ«Œ^|j-|%|||$j=d'«|$j=d(«|$j=d)«d*œ«Œ¤�Œp�ŒÍnª|d+vr˜|d,k(rd-nd.}& t?|
|||&¬/«}'|'D]y\}(})}*}+t+|«|k\rns|j)|)«sŒ*|dk(r|j-|)|(dœ«ŒD|dk(r|j-|)|(|*ddd2œ«Œa|j-|)|(|*ddd|+d3œ«Œ{ntd4|›�«‚|||||t+|«|t+|«|k(d5œS#t$r} tt| ««| ‚d} ~ wwxYw#t$r,} tjd | ›�«td
| ›�«| ‚d} ~ wwxYw#t$rg}
Y�ŒwwxYwcc}w#t$rg}Y�Œ½wxYw#t$rY�Œ¤wxYwcc}wcc}"w#t$rY�ŒFwxYw#t$r(} tjAd0|›d1| ›�«g}'Yd} ~ �ŒŠd} ~ wwxYw)6u
按对象类型在已�置的业务库中探索 schema�表�列�索引�存储过程/函数等元数�(对� DBHub search_objects)。
会过滤系统 schema(如information_schema�sys�pg_catalog 等),�按 object_type 与 pattern � SQL LIKE 风格匹�;
:param object_type: �探索的对象类别。schema-模��;table-数�表;column-列(�与 table�schema �用
�定�表);index-索引(�上);procedure-存储过程;function-函数(标�/表值等,视库而定)。
:param pattern: SQL LIKE 模�,默认 "%" 表示�过滤�称。"%" 匹�任�长度�串,"_" 匹��个字符;对表��
列��索引��例程�等�大�写��感匹�。
:param schema: �定在�个 schema 内查找;None 表示在多个�系统 schema 上�次查找。若给出具体�称,
必须是库中已存在的 schema,�则抛 ValueError。使用�数 table 时必须�时指定 schema。
:param table: 仅在 object_type 为 column 或 index 时�许传入,与 schema 共��定「�查这一张表或视图�上的列
或索引;用于其它 object_type 时会抛 ValueError。�称会在该 schema 下与�射得到的表��视图��
�区分大�写匹�(并支� [Name] 写法),以兼容 SQL Server 等对目录大�写��感但 API 需真实写法的情况。
:param detail_level: 返回粒度。names-仅对象��定�字段(如 schema�table);summary-增加简�元数�
(如表的 column_count�row_count,列的类型��空等);full-表级返回列列表�索引列表等完整结构。
:param limit: 最多返回的结果�数,默认 100,有效范围 1~1000(传入值会被夹紧到该区间)。
:return: 包� object_type�pattern�schema�table�detail_level�count�results�truncated 的字典。
未�置 database_url�连接失败或内�失败时抛出 ValueError(或其它底层异常)。
z7The 'table' parameter requires 'schema' to be specified)r!r$zLThe 'table' parameter only applies to object_type 'column' or 'index', not 'Ú'r@ièNr/r%r3r&u _search_objects inspect 失败: uæ•°æ�®åº“内çœ�失败: rôz(none)zSchema 'z%' does not exist. Available schemas: rr%rCrN)rCÚ table_countr )rCrr&)rCrÚ column_countÚ row_countrŸr›rœr�r˜rž)rCr–r—ršr )rCrrGrHr‚Úindexesr!)rCr r)rCr rr–r—ršr‚r�rƒ)rCr rr‚r�rƒ)r"r#r"Ú PROCEDUREÚFUNCTION)r°r±u+_search_objects 例程列表失败 dialect=z: )rCrr–ÚlanguageÚ return_type)rCrr–rLÚ
parametersrMÚ
definitionzUnsupported object_type: )Ú object_typer;rr Ú detail_levelr-Úresultsr)!rørÑr/rmr>rrrrrr
r0r2r„Úget_schema_namesrRr^r9r`rCrÐrIr5rPrDr¨rrr”r‹rYrzr½r>),rPr;rr rQÚlimitÚlimÚpatÚrxr3rdr6rSÚall_schema_namesÚfiltered_schemasÚavailÚschemas_to_searchr`rRÚ base_schemasr]Ú
candidatesÚ schema_nameÚtblsÚ
table_namerXr}ÚrcrŸÚ result_dictÚidxsr=Úresult_dict_fullÚtables_to_searchrKÚresult_dict_colrŠÚinamer®Ú routine_rowsr­rCr¼rµs, rÚ_search_objectsrisž€ñ4