Files
ai-g3sb-backman2.0/tools/__pycache__/dbhub_tools.cpython-311.pyc
T

444 lines
56 KiB
Plaintext
Raw Normal View History

2026-04-14 10:28:22 +08:00
§
WšÜiP½ãó˜—dZddlmZddlZddlZddlmZddlmZm Z ddl
m Z m Z ddl
mZddlmZdd lmZdd
lmZdd lmZdd lmZmZdd
lmZmZmZmZmZe dZ e dZ!e"hd£¦«Z#dmd„Z$dnd„Z%dnd„Z&dod„Z'dpd!„Z(dqd$„Z)drd&„Z*dsd)„Z+dtd+„Z,dud,„Z-dtd-„Z.dvd2„Z/dwd5„Z0e"hd6£¦«Z1ej2d7¦«Z3dxd;„Z4dyd=„Z5dzd?„Z6d{d@„Z7d{dA„Z8d|dD„Z9d}dH„Z:d~dK„Z;ddN„Z<dOddPœd€dS„Z=dOdTœd�dU„Z>dOdTœd‚dW„Z? dƒd„db„Z@Gdc„dd¦«ZAeA¦«ZBd…df„ZCd†dg„ZDd†dh„ZEd‡di„ZFdˆdk„ZGeHdlkr eG¦«dSdS)‰u?
与 DBHub 对�的数�库工具:search_objects(元数�探索)�execute_sql(SQL 执行,对� execute-sql.ts)�
execute_sql_all(� execute_sql 但�截断行数)�execute_sql_count_only(仅统计行数,�返回明细)。
- 模�级 ``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)Ú get_optional)Úlog)Ú
get_engine)Úallowed_keywords_listÚis_read_only_sql)Ú
ConnectorTypeÚ _get_scannerÚ _TOKEN_PLAINÚsplit_sql_statementsÚstrip_comments_and_strings)ÚschemaÚtableÚcolumnÚ procedureÚfunctionÚindex)ÚnamesÚsummaryÚfull>ÚsysÚmysqlÚpg_toastÚ
pg_catalogÚinformation_schemaÚperformance_schemaÚpatternÚstrÚreturnúre.Pattern[str]có>—g}|D]a}|dkr| d¦«Œ|dkr| d¦«Œ:| tj|¦«¦«Œbtjdd |¦«zdztj¦«S)u_SQL LIKE → regex,与 DBHub likePatternToRegex 一致(% / _,其余字符 re.escape)。ú%z.*Ú_ú.ú^Úú$)ÚappendÚreÚescapeÚcompileÚjoinÚ
IGNORECASE)r$ÚpartsÚcs ú<D:\CodeSpace\afe-ai\ai-g3sb-backman\src\tools\dbhub_tools.pyÚ_like_pattern_to_regexr80s—€à€EØ
ð'ð'ˆØ �Š8ˆ8Ø �LŠL˜Ñ Ô Ð Ð Ø
�#ŠXˆXØ �LŠL˜Ñ Ô Ð Ð à �LŠL�œ 1™œÑ &Ô &Ð &Ð &Ý
Œ:�c˜BŸGšG E™NœNÑ*¨SÑ0µ"´-Ñ @Ô @Ð@óÚnamecó‚—| ¦« dd¦«d ¦«S)Nr+ééÿÿÿÿ)ÚstripÚrsplit)r:s r7Ú_bare_table_namer@=s1€Ø �:Š:‰<Œ<× Ò ˜s AÑ &Ô & rÔ *× 0Ò 0Ñ 2Ô 2Ð2r9cóÀ—| ¦«}t|¦«dkr6|ddkr*|ddkr|dd… dd¦«S|S)uJ去掉首尾空白;若整段为 [Name] å½¢å¼�则去括å�·ï¼ˆå�•层)。érÚ[r=Ú]r<z]])r>ÚlenÚreplace)r:Úts r7Ú_normalize_user_object_namerHAsW€à �
Š
‰ Œ €AÝ
ˆ1�v„v�‚{€{�q˜”t˜s’{�{ q¨¤u°¢| |Ø��2�Œw�Š˜t SÑ)Ô)Ð)Ø €Hr9Úinsprrú
str | NoneÚ
user_tablecóN—t|¦«}|s| ¦«S| ¦«}|j|jfD]\} ||¬¦«D]<}t t
|¦«¦«}| ¦«|kr|ccSŒ=ŒM#t$rYŒYwxYw|S)u¬
将用户输入的表/视图�解�为与 SQLAlchemy inspect 一致��在 get_columns/get_indexes 中使用的�称。
SQL Server 等库对标识符大�写��感,但�射时传入与系统目录�一致的大�写�能导致 get_columns 返回空;
视图�在 get_table_names 中,仅传表�会�匹�。本函数在指定 schema 下对表�与视图���区分大�写对�。
©r)rHr>ÚlowerÚget_table_namesÚget_view_namesr@r%Ú Exception)rIrrKÚwantÚkeyÚlisterÚrawÚbares r7Ú _resolve_table_or_view_bare_namerWIs×€õ ' zÑ 2Ô 2€DØ ð"Ø×ÒÑ!Ô!Ð!Ø
�*Š*‰,Œ,€CØÔ'¨Ô)<Ð=ððˆð Ø�v VÐ,Ñ,Ô,ð
ð
�Ý'­¨C©¬Ñ1Ô1�Ø—:’:‘<”< 3Ò&Ð&Ø�K�K�K�K�Kð'ð
øõð ð ð Ø ˆHð øøøà €KsÁ ABÂBÂ
B"Â!B"rUú list[str]có—d„|D¦«S)NcóL—g|]!}|¯| ¦«tv¯|‘Œ"S©)rNÚ
_SKIP_SCHEMAS)Ú.0Úss r7ú
<listcomp>z#_filter_schemas.<locals>.<listcomp>`s/€Ð CÐ CÐ C�!˜aÐ C A§G¢G¡I¤Iµ]Ð$BÐ$BˆAÐ$BÐ$BÐ$Br9r[)rUs r7Ú_filter_schemasr`_s€Ø CÐ C�sÐ CÑ CÔ CÐCr9ÚengineÚ
bare_tablecó€—|jj}| |¦«}|r| |¦«›d|›�S|S)Nr+)ÚdialectÚidentifier_preparerÚquoteÚ quote_schema)rarrbÚprepÚtqs r7Ú_qualified_table_sqlrjcsL€Ø Œ>Ô -€DØ
�Š�JÑ Ô €BØ
ð3Ø×#Ò# FÑ+Ô+Ð2Ð2¨bÐ2Ð2Ð2Ø
€Ir9ú
int | Nonecó`—t|||¦«} | ¦«5}| td|›�¦«¦«}| ¦«}|€ ddd¦«dSt |d¦«cddd¦«S#1swxYwYdS#t $rYdSwxYw)NzSELECT COUNT(*) AS c FROM r)rjÚconnectÚexecuterÚfetchoneÚintrQ)rarrbÚqÚconnÚrÚrows r7Ú_table_row_countruks€Ý˜V V¨ZÑ8Ô8€AðØ
�^Š^Ñ
Ô
ð  Ø— ’ �TÐ"B¸qÐ"BÐ"BÑCÔCÑDÔDˆAØ—*’*‘,”,ˆC؈{Øð  ð ð ñ ô ð ð ð õ
�s˜1”v‘;”;ð  ð ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ð øõ ððð؈tˆtðøøøs@“B§=BÁ$ BÁ1B BÂBÂBÂBÂBÂ
B-Â,B-rVútuple[str, ...]có´— | ||¬¦«}| d¦«pg}td„|D¦«¦«S#t$rYdSwxYw)NrMÚconstrained_columnsc3ó4K—|]}t|¦«V—ŒdS©N)r%©r]r6s r7ú <genexpr>z_pk_columns.<locals>.<genexpr>|s(èè€Ð*Ð* •S˜‘V”VÐ*Ð*Ð*Ð*Ð*Ð*r9r[)Úget_pk_constraintÚgetÚtuplerQ)rIrrVÚpkÚcolss r7Ú _pk_columnsr‚xsu€ðØ
×
#Ò
# D°Ð
#Ñ
8Ô
8ˆØ�vŠvÐ+Ñ,Ô,Ð2°ˆÝÐ*Ð* TÐ*Ñ*Ô*Ñ*Ô*Ð*øÝ ððð؈rˆrðøøøs‚AA Á
AÁAúlist[dict[str, Any]]cóî—t|||¦«} t| ||¬¦«¦«}n#t$rgcYSwxYwg}|D]¦}t| d¦«pg¦«}t | d¦«¦«}t |¦«ot
|¦«|k} | t| d¦«pd¦«||| dœ¦«Œ§|S)NrMÚ column_namesÚuniquer:r-)r:Úcolumnsr†Úprimary) r‚ÚlistÚ get_indexesrQr~Úboolrr/r%)
rIrrVÚpk_colsÚraw_idxÚoutÚidxr�r†rˆs
r7Ú _index_dictsr��s€Ý˜$ ¨Ñ-Ô-€GðÝ�t×'Ò'¨°VÐ'Ñ<Ô<Ñ=Ô=ˆˆøÝ ðððØˆ ˆ ˆ ðøøøà "€CØð 
ð 
ˆÝ�C—G’G˜NÑ+Ô+Ð1¨rÑ2Ô2ˆÝ�c—g’g˜hÑ'Ô'Ñ(Ô(ˆÝ�w‘-”-Ð:¥E¨$¡K¤K°7Ò$:ˆØ �
Š
å˜CŸGšG F™OœOÐ1¨rÑ2Ô2ØØ Ø"ð 
ð
ñ
ô
ð
ð
ð €Js“$8¸ AÁAcó— | ||¬¦«}t|t¦«r/| d¦«pd ¦«}|r|ndSn(#t
t tf$rYnt$rYnwxYwdS)u;获å�–表注释,若ä¸�支æŒ�或无注释则返回 None。rMrr-N) Úget_table_commentÚ
isinstanceÚdictr~r>ÚNotImplementedErrorÚAttributeErrorÚ TypeErrorrQ)rIrrVÚtcrs r7Ú_table_commentr™—sª€ð
Ø
×
#Ò
# D°Ð
#Ñ
8Ô
8ˆÝ �b�$Ñ Ô ð *Ø—F’F˜6‘N”NÐ( b×/Ò/Ñ1Ô1ˆDØÐ)�4�4 TÐ )ð *øõ
¥µÐ ;ð
ð
ð
Ø ˆÝ ð
ð
ð
Ø ˆð
øøøà ˆ4s‚AAÁBÁ7 BÂBcó
— t| ||¬¦«¦«}n#t$rgcYSwxYwg}|D�]D}t|t¦«sŒt | d¦«pd¦« ¦«}|sŒR| d¦«}|�!t |¦« ¦«nd}| d¦«} | dup,t| t
¦«o|  ¦«dk}
|||
rdnd| d ¦«d
œ} | d ¦«} | �(t | ¦« ¦«}
|
r|
| d <|  | ¦«�ŒF|S)
NrMr:r-ÚtypeÚnullableTÚYESÚNOÚdefault)Ú column_nameÚ data_typeÚ is_nullableÚcolumn_defaultÚcommentÚ description)
r‰Ú get_columnsrQr“r”r%r~r>Úupperr/)rIrrVr�rŽr6ÚfnameÚftypeÚdtyperœÚnull_bÚentryr¤Ú comment_strs r7Ú
_column_dictsr®¥s¡€ðÝ�D×$Ò$ T°&Ð$Ñ9Ô9Ñ:Ô:ˆˆøÝ ðððØˆ ˆ ˆ ðøøøà "€CØ
ðñˆÝ˜!�TÑ"Ô"ð Ø Ý�A—E’E˜&‘M”MÐ' RÑ(Ô(×.Ò.Ñ0Ô0ˆØð Ø Ø—’�f‘
”
ˆØ&+Ð&7•�E‘
”
× Ò Ñ"Ô"Ð"¸RˆØ—5’5˜Ñ$Ô$ˆØ˜TÐ!Ð^¥j°½3Ñ&?Ô&?Ð&]ÀHÇNÂNÑDTÔDTÐX]ÒD]ˆà ØØ$*Ð4˜5˜5°ØŸeše IÑ.Ô.ð !
ð!
ˆð—%’%˜ Ñ"Ô"ˆØ Рݘg™,œ,×,Ò,Ñ.Ô.ˆKØð
3Ø'2��mÑ$Ø �
Š
�5ÑÔÐÑØ €Js ‚$'§ 6µ6rdÚ
schema_filterÚroutine_sql_typeú>list[tuple[str, str, str, str | None, str | None, str | None]]c
ód—g}|dvr|Sd}i}|r
|dz
}||d<|r
|dz
}||d<| ¦«5}| t|¦«|¦«D]o}|d} | t |d¦«t |d ¦«t |d
¦«| €d nt | ¦«d d f¦«Œp d d d ¦«n #1swxYwY|d v�rF|�rC d
}
i} |r
|
dz
}
|| d<|r
|
dz
}
|| d<i} | t|
¦«| ¦«D]•}t |d¦«t |d ¦«f}
|d
r't |d
¦« ¦«nd }|dr't |d¦« ¦«nd }||f| |
<Œ–g}|D]S\}}}} }}||f}
|
| vr'| |
\}}| |||| ||f¦«Œ8| |||| d d f¦«ŒT|}n#t $rYnwxYw|S)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<rBN)rrµz³
SELECT ROUTINE_SCHEMA, ROUTINE_NAME, EXTERNAL_LANGUAGE, DTD_IDENTIFIER
FROM INFORMATION_SCHEMA.ROUTINES
WHERE 1=1
)rmrnrr/r%r>rQ)rardr¯r°ÚrowsÚsqlÚparamsrrrsÚdefnÚ extra_sqlÚ extra_paramsÚ extra_maprSÚlangÚret_typeÚ updated_rowsr¶r:Úrtyper*s r7Ú_fetch_routinesrÄÅs€ð LN€DØÐAÐAÐA؈ ð €Cð
 €FØð&Ø Ð+Ñ+ˆØ%ˆˆu‰
Øð(Ø Ð(Ñ(ˆØ'ˆˆt‰ à �ŠÑ Ô ð ˜TØ—’�d 3™iœi¨Ñ0Ô0ð ð ˆAØ�Q”4ˆDØ �KŠK嘘!œ‘I”Iݘ˜!œ‘I”Iݘ˜!œ‘I”IØ ˜L�D�D­c°$©i¬iØØð
ñ
ô
ð
ð
ð ð ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ðÐ&Ð&Ñ&¨4Ñ&ð! ðˆIð
,.ˆLØð
4ØÐ9Ñ9� Ø&3� ˜UÑ#Øð
6ØÐ6Ñ6� Ø%5� ˜TÑ"àNPˆIØ—\’\¥$ y¡/¤/°<Ñ@Ô@ð
2ð
2�ݘ1˜Qœ4‘y”y¥# a¨¤d¡)¤)Ð,�Ø,-¨a¬DÐ:•s˜1˜Qœ4‘y”y—’Ñ(Ô(Ð(°d�Ø01°!´Ð>�3˜q œt™9œ9Ÿ?š?Ñ,Ô,Ð,¸$�Ø"&¨Ð!1� ˜#‘�ð\^ˆLØ04ð
Nð
NÑ,��T˜5 $¨¨1ؘD�k�ؘ)Ð#Ð#Ø%.¨s¤^‘N�D˜(Ø ×'Ò'¨¨d°E¸4ÀÀxÐ(PÑQÔQÐQÐQà ×'Ò'¨¨d°E¸4ÀÀtÐ(LÑMÔMÐMÐM؈DˆDøÝð ð ð à ˆDð øøøð €Ks%¹BCÃCÃ!CÃ.D1H È
H-È,H-Ú dialect_namercó>—ddddddœ}| |d¦«S)už
将 SQLAlchemy dialect.name 映射到 DBHub ConnectorType。
未知方言按 postgres 规则��读校验(与 DBHub 移�约定一致)。
ÚpostgresrrµÚsqliteÚ sqlserver)r´rrµrÈr³)r~)rÅÚms r7Úsqlalchemy_dialect_to_connectorrËs5€ð !ØØØØð #ð#€Að
�5Š5�˜zÑ *Ô *Ð*r9>Ú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*\(rºÚ connectorútuple[int, str] | Nonecóè—t||¦«dkrdSt|¦«}t|¦«}d}d}d}d}d}||k�r,|||¦«} | dtkr | d}Œ-|dkrVt jd|||…¦«}
|
r1d}||
 ¦«z}||
 ¦«z
}Œƒ|d z
}Œ‰|dkrYt jd
|||…¦«} | r:|||…} t jd |  ¦«¦«rdS|d z| fS||}
|
d kr|d z
}n+|
d
krtd|d z
¦«}n|
dkr |dkr|d z
}|d z
}||k�°,dS)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_keywordrrErr0ÚmatchrÓr>Úmax)rºrÏÚscanÚnÚiÚ
list_parenÚ
col_commasÚstateÚ
list_startÚtokrÊÚmfÚfragr6s r7Ú_parse_top_level_select_listrå4s¿€õ
˜#˜yÑ)Ô)¨VÒ3Ð3؈tÝ ˜ Ñ "Ô "€DÝ ˆC‰Œ€AØ €AØ€JØ€JØ+4€EØ€JØ
ˆaŠ%‰%؈d�3˜‰lŒlˆØ ˆvŒ;�,Ò &Ð &Ø�E”
ˆAØ Ø �IÒ Ð Ý”Ð*¨C°°!°¬HÑ5Ô5ˆAØð
Ø!�Ø §¢¡¤™[�
Ø�Q—U’U‘W”W‘ �ØØ
�‰FˆAØ Ø ˜Š?ˆ?Ý”Ð*¨C°°!°¬HÑ5Ô5ˆBØð
.ؘ: a˜<Ô(�Ý”8Ð.°·
²
± ´ Ñ=Ô=ð Ø˜4Ø" Q™¨Ð-Ð-Ø �ŒFˆØ �Š8ˆ8Ø ˜!‰OˆJˆJØ
�#ŠXˆXݘQ 
¨Q¡Ñ/Ô/ˆJˆJØ
�#ŠXˆX˜*¨š/˜/Ø ˜!‰OˆJØ ˆQ‰ˆð9 ˆaŠ%‰%ð: ˆ4r9r‹có`—t|¦«}t|¦«}d}d}||kr…|||¦«}|dtkr |d}Œ,|dkr!tjd|||…¦«}|rdS||}|dkr|dz
}n|dkrt d|dz
¦«}|dz
}||k°…d S)
Nrr›rÓz(?is)\bgroup\s+by\bTrÕr<rÖF)rrErr0rÙrÚ) rºrÏrÛrÜrÝÚdepthrârÊr6s r7Ú_has_top_level_group_byrèbsÛ€Ý ˜ Ñ "Ô "€DÝ ˆC‰Œ€AØ €AØ
€EØ
ˆaŠ%ˆ%؈d�3˜‰lŒlˆØ ˆvŒ;�,Ò &Ð &Ø�E”
ˆAØ Ø �AŠ:ˆ:Ý”Ð/°°Q°q°S´Ñ:Ô:ˆAØð
Ø�tØ �ŒFˆØ �Š8ˆ8Ø �Q‰JˆEˆEØ
�#ŠXˆXݘ˜5 1™9Ñ%Ô%ˆEØ ˆQ‰ˆð ˆaŠ%ˆ%ð ˆ5r9Úinnercó—t||¦«}|€dS|\}}|dkrdSt||¦«rdS| ¦«}|rtjd|¦«rdSt t  |¦«¦«S)u‹å�•列ã€�æ—  GROUP BYã€�且选择列表以常è§�è�šå�ˆå‡½æ•°å¼€å¤´æ—¶ï¼Œç»“果集为标é‡�,宜直接执行内层而é�ž COUNT(*) 包裹。NFr<z (?is)^\*\s*$)rårèr>r0rÙr‹Ú_AGGREGATE_SCALAR_PREFIX)rérÏÚparsedÚncolsräÚfss r7Ú_is_aggregate_scalar_fast_pathrïys“€å
)¨%°Ñ
;Ô
;€FØ
€~؈uØ�K€Eˆ4Ø �‚z€z؈uݘu iÑ0Ô0ð؈uØ
�ЉŒ€BØ
𕔘/¨2Ñ.Ô.ð؈uÝ Õ(×.Ò.¨rÑ2Ô2Ñ 3Ô 3Ð3r9có.—|dvr|St|¦«}t|¦«}d}d}d}||kr�|||¦«}|dtkr |d}Œ,|dkr9tjd|||…¦«}|r|}|| ¦«z
}Œk||} | dkr|dz
}n| d krt
d|dz
¦«}|dz
}||k°�|dkr|S|d
|… ¦« d ¦« ¦«S) uI
SQL Server / MySQL / MariaDB:派生表内 ``ORDER BY`` 若无 TOP/OFFSET/LIMIT 会报语法错误。
在 COUNT �查询包装�去掉最外层(括�深度为 0)最�一次出现的 ``ORDER BY`` �其�内容;
�改�行数统计语义。注释与字符串内的括�/关键字��与解�。
©rÉrrµrr=r›rÓz(?is)order\s+by\brÕr<rÖNú;)rrErr0rÙrÓrÚÚrstrip)
rºrÏrÛrÜrÝrçÚlast_order_by_startrârÊr6s
r7Ú_strip_outer_trailing_order_byrõ‰sL€ð Ð9Ð9Ð9؈
Ý ˜ Ñ "Ô "€DÝ ˆC‰Œ€AØ €AØ
€EØÐØ
ˆaŠ%ˆ%؈d�3˜‰lŒlˆØ ˆvŒ;�,Ò &Ð &Ø�E”
ˆAØ à �AŠ:ˆ:Ý”Ð-¨s°1°Q°3¬xÑ8Ô8ˆAØð
Ø&'Ð#Ø�Q—U’U‘W”W‘ �ØØ �ŒFˆØ �Š8ˆ8Ø �Q‰JˆEˆEØ
�#ŠXˆXݘ˜5 1™9Ñ%Ô%ˆEØ ˆQ‰ˆð# ˆaŠ%ˆ%ð$˜QÒÐØˆ
Ø Ð#Ð#Ð#Ô $× +Ò +Ñ -Ô -× 4Ò 4°SÑ 9Ô 9× @Ò @Ñ BÔ BÐBr9cóÊ—t||¦«}| ¦« ¦«}tjd|¦«}|r| d¦«ndS)uK剥离注释与字符串字é�¢é‡�å�Žï¼Œå�–首个é�žç©ºç™½è¯�(å°�写)。z\S+rr-)rr>rNr0ÚsearchÚgroup)rºrÏÚcleanedrÊs r7rØrØ­sT€å(¨¨iÑ8Ô8€GØ�mŠm‰oŒo×#Ò#Ñ%Ô%€GÝ
Œ �&˜'Ñ"Ô"€AØÐ "ˆ1�7Š7�1‰:Œ:ˆ: Ð"r9Ú inner_sqlrícóð—| ¦«}|std¦«‚t||¦«}d|›d�}|�8|dvr4d d„t |¦«D¦«¦«}|›d|›d�S|S) NõSQL ä¸�能为空z&SELECT COUNT(*) AS __dbhub_cnt FROM (
z
) AS __dbhub_subqrñú, c3ó K—|] }d|›�V—Œ
dS)Ú __dbhub_cNr[)r]Úks r7r|z%_sql_wrapped_count.<locals>.<genexpr>Äs(èè€Ð@Ð@¨a˜/ a˜/˜/Ð@Ð@Ð@Ð@Ð@Ð@r9z (rÖ)r>Ú
ValueErrorrõr3Úrange)rúrÏríréÚcorers r7Ú_sql_wrapped_countrµsª€ð
�OŠOÑ Ô €EØ ð-ÝÐ+Ñ,Ô,Ð,Ý *¨5°)Ñ <Ô <€Eð Ø ð ð ð ð ð

ИYÐ*KÐKÐKØ— ’ Ð@Ð@µ5¸±<´<Ð@Ñ@Ô@Ñ@Ô@ˆØÐ"Ð"˜%Ð"Ð"Ð"Ð"Ø €Kr9r Ú
statementsrpcóΗ| ¦«5}t|¦«D�]¥\}}| ¦«}|t|¦«dz
kr>| t |¦«¦«}|jr| ¦«Œn|std¦«‚t||¦«}|tv�r»t| ¦«|¦«} t| |¦«r¥| t | ¦«¦«}| 
¦«}
|
�|
d€ddd¦«dS|
d} t| t¦«rt!| ¦«ccddd¦«St!| ¦«ccddd¦«St#| |¦«} | €S| t | ¦«¦«}|jsddd¦«dSd}
|D]}|
dz
}
Œ|
ccddd¦«S| \}}t%| ||¦«}| t |¦«¦«}| 
¦«}
|
€ddd¦«dSt!|
d¦«ccddd¦«S| t |¦«¦«}|jsddd¦«dSd}
|D]}|
dz
}
Œ|
ccddd¦«S ddd¦«dS#1swxYwYdS)uÊ
顺�执行多�语�;对最�一�:优先用 COUNT �查询��标�(select/with/explain),
�则�次执行�在 Python 侧�行计数(�组装 rows 明细)。
r<õ
SQL 为空Nr)rmÚ enumerater>rErnrÚ returns_rowsÚfetchallrrØÚ_COUNT_WRAP_FIRST_WORDSrõrïror“rrprår)rarrÏrrrÝÚstmtr^rsÚfirstrértÚcellrìrÜr*ríÚ_fragÚwrappeds r7Ú"_execute_sql_statements_count_onlyrÉs0€ð
�ŠÑ Ô ð,˜TÝ  Ñ,Ô,ð+ ñ+ ‰GˆAˆtØ—
’
‘ ” ˆAØ•3�z‘?”? QÑ&Ò&Ð&Ø—L’L¥ a¡¤Ñ)Ô)�Ø”>ð!Ø—J’J‘L”L�LØØð
/Ý  Ñ.Ô.Ð.Ý& q¨)Ñ4Ô4ˆEØÕ/Ð/Ñ/Ý6°q·w²w±y´yÀ)ÑLÔL�Ý1°%¸ÑCÔCð%ØŸ š ¥T¨%¡[¤[Ñ1Ô1�AØŸ*š*™,œ,�CØ�{ c¨!¤f nØ ð#,ð,ð,ñ,ô,ð,ð,ð,ð$˜qœ6�DÝ! $­Ñ0Ô0ð)Ý" 4™yœyÐ(Ð(ð),ð,ð,ð,ñ,ô,ð,ð,õ*˜t™9œ9Ð$Ð$ð+,ð,ð,ð,ñ,ô,ð,ð,õ,6°e¸YÑGÔG�Ø�>ØŸ š ¥T¨%¡[¤[Ñ1Ô1�AØœ>ð!Ø ð5,ð,ð,ñ,ô,ð,ð,ð,ð6�AØðð˜Ø˜Q™˜˜Ø�H�Hð=,ð,ð,ð,ñ,ô,ð,ð,ð> &‘ ��uÝ,¨U°I¸uÑEÔE�Ø—L’L¥ g¡¤Ñ/Ô/�Ø—j’j‘l”l�Ø�;ØðI,ð,ð,ñ,ô,ð,ð,ð,õJ˜3˜qœ6‘{”{Ð"Ð"ðK,ð,ð,ð,ñ,ô,ð,ð,ðL— ’ �T !™WœWÑ%Ô%ˆAØ”>ð
ØðQ,ð,ð,ñ,ô,ð,ð,ð,ðRˆAØð
ð
�Ø�Q‘��؈HˆHðY,ð,ð,ð,ñ,ô,ð,ð,ð+ ð,ð,ð,ñ,ô,ð,ð,ð,ð,ð,ð,ð,øøøð,ð,ð,ð,ð,ð,sC•DKÄ>-KÅ8KÆ<KÇKÇ:AKÉKÉ9*KÊ0KËKË!KÚvalÚobjectcó<—t|t¦«rt|¦«St|ttf¦«r$t|¦« dd¬¦«St
|d¦«r' | ¦«S#t$r|cYSwxYw|S)Nzutf-8rF)ÚerrorsÚ isoformat) r“rr%ÚbytesÚ bytearrayÚdecodeÚhasattrrrQ)rs r7Ú_serialize_sql_cellrs£€Ý�#•wÑÔðÝ�3‰xŒxˆÝ�#��yÐ)Ñ*Ô*ð<Ý�S‰zŒz× Ò  °Ð Ñ;Ô;Ð;݈s�KÑ Ô ðð Ø—=’=‘?”?Ð "øÝð ð ð ØˆJˆJˆJð øøøà €JsÁ6B
Â
BÂBÚmax_rowsú/tuple[list[str], list[dict[str, object]], bool]có>—g}g}d}| ¦«5}d}t|¦«D�]T\}} |  ¦«}
| t |
¦«¦«}|t |¦«dz
kr|jr| ¦«Œn|jsg}g}d}nÙt|  ¦«¦«}|€| ¦«} d}nRtdt|¦«¦«} |  | dz¦«}
t |
¦«| k}|
d| …} g}| D]F}i}t|¦«D]\}}t||¦«||<Œ| |¦«ŒG�ŒVddd¦«n #1swxYwY|||fS)u•顺åº�执行多æ�¡è¯­å�¥ï¼Œä»…返回最å�Žä¸€æ�¡æœ‰ç»“果集语å�¥çš„列与行。``max_rows`` 为 None 时对最å�Žä¸€æ�¡ ``fetchall``,ä¸�截断。FNr<)rmrr>rnrrEr r
r‰ÚkeysrÚrpÚ fetchmanyrr/)rarrÚ last_colsÚ last_rowsÚ truncatedrrÚresultrÝr r^Ú rows_dataÚmrÚfetchedrtÚrow_mapÚjÚcols r7Ú_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œMÑ*Ô*�Ø ×*Ò*¨2°©6Ñ2Ô2�Ý ™LœL¨2Ò-� Ø# C R CœL� ؈IØ ð
*ð
*�Ø-/�Ý'¨ Ñ2Ô2ð?ð?‘F�A�sÝ#6°s¸1´vÑ#>Ô#>�G˜C‘L�LØ× Ò  Ñ)Ô)Ð)Ð)ñ 
*ð1*ð*ð*ñ*ô*ð*ð*ð*ð*ð*ð*øøøð*ð*ð*ð*ð: �i Ð *Ð*s›E(FÆFÆFT©Úreadonlyrr-údict[str, object]c ó¸—|pd ¦«}|std¦«‚td¦«pd ¦«}|std¦«‚t¦«}t |jj¦«}t||¦«}|std¦«‚|rK|D]H}t||¦«s6d  t|¦«¦«pd} td| ›�¦«‚ŒI|�|nttd
¦«pd ¦«}
td td t|
¦«¦«¦«}
tjd
t!|¦«›d|›d|
›�¦« t#|||
¬¦«\} } }
nF#t$$r9}tjd|›�¦«tt)|¦«¦«|‚d }~wwxYwt!| ¦«}| || |
dœS)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(�行一个 dict,列�到值的映射)�count(等于 rows 长度,等� DBHub rowCount)�
columns(列�列表)�truncated(是�因超过 max_rows 而截断)。
最�一�语�无结果集时 rows�columns 为空,count 为 0。未�置 database_url�SQL 为空或执行失败时
抛出 ValueError(或包装�的底层异常信�)。
r-rüÚ database_urlõdatabase_url 未é…�ç½®rrýÚ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¹Úcountr‡r#)r>rr r
rËrdr:rrr3rrprÚÚminr ÚinforEr+rQÚerrorr%)rºr-rrUÚurlrarÏrÚstÚkwr&r�r¹r#Úer8s r7Ú _execute_sqlr@8s€ð& ˆ9�"×
Ò
Ñ
Ô
€CØ ð-ÝÐ+Ñ,Ô,Ð,å ˜Ñ 'Ô 'Ð -¨2×
4Ò
4Ñ
6Ô
6€CØ ð3ÝÐ1Ñ2Ô2Ð2å
‰\Œ\€FÝ/°´Ô0CÑDÔD€IÝ% c¨9Ñ5Ô5€Jà ð'ݘÑ&Ô&Ð&àðØð ð ˆBÝ# B¨ Ñ2Ô2ð
Ø—Y’YÕ4°YÑ?Ô?Ñ@Ô@ÐJÀF�Ý ØeÐacÐeÐeñôðð
ð Ð)ˆˆ­sµ<ÀÑ3OÔ3OÐ3XÐSXÑ/YÔ/Y€BÝ ˆQ•�E�3˜r™7œ7Ñ#Ô#Ñ $Ô $€Bå„HÐ
`­S°©_¬_Ð
`Ð
`ÈÐ
`Ð
`Ð\^Ð
`Ð
`ÑaÔaÐað(Ý 7¸À
ÐUWÐ XÑ XÔ Xшˆd�I�IøÝ ð(ð(ð(Ý Œ Ð3°Ð3Ð3Ñ4Ô4Ð4Ý�˜Q™œÑ Ô  aÐ'øøøøð(øøøõ
�‰IŒI€EàØØØð  ð ðsÅ)FÆ
GÆ
4F>Æ>G©r-có—|pd ¦«}|std¦«‚td¦«pd ¦«}|std¦«‚t¦«}t |jj¦«}t||¦«}|std¦«‚|rK|D]H}t||¦«s6d  t|¦«¦«pd}td|›�¦«‚ŒItj d t|¦«›d
|›�¦« t||d ¬ ¦«\} }
} nF#t$r9} tjd
| ›�¦«tt#| ¦«¦«| ‚d } ~ wwxYwt|
¦«}
|
|
| | dœS)uõ
与 ``_execute_sql`` 相�校验与返回结构,但对最�一�有结果集的语��� ``max_rows`` 截断,全部 ``fetchall``。
超大结果集会�用大�内存,仅用于�信 SQL / 已自行 LIMIT 的场景。
r-rür0r1rrýr2r3u!_execute_sql_all 执行语å�¥æ•°=r5Nr6u_execute_sql_all 执行失败: r7)r>rr r
rËrdr:rrr3rr r:rEr+rQr;r%)rºr-rUr<rarÏrr=r>r�r¹r#r?r8s r7Ú_execute_sql_allrCvsÒ€ð ˆ9�"×
Ò
Ñ
Ô
€CØ ð-ÝÐ+Ñ,Ô,Ð,å ˜Ñ 'Ô 'Ð -¨2×
4Ò
4Ñ
6Ô
6€CØ ð3ÝÐ1Ñ2Ô2Ð2å
‰\Œ\€FÝ/°´Ô0CÑDÔD€IÝ% c¨9Ñ5Ô5€Jà ð'ݘÑ&Ô&Ð&àðØð ð ˆBÝ# B¨ Ñ2Ô2ð
Ø—Y’YÕ4°YÑ?Ô?Ñ@Ô@ÐJÀF�Ý ØeÐacÐeÐeñôðð
õ „HÐ
Vµ°Z±´Ð
VÐ
VÈHÐ
VÐ
VÑWÔWÐWð(Ý 7¸À
ÐUYÐ ZÑ ZÔ Zшˆd�I�IøÝ ð(ð(ð(Ý Œ Ð7°AÐ7Ð7Ñ8Ô8Ð8Ý�˜Q™œÑ Ô  aÐ'øøøøð(øøøõ
�‰IŒI€EàØØØð  ð ðsÄD0Ä0
E3Ä:4E.Å.E3údict[str, int]có—|pd ¦«}|std¦«‚td¦«pd ¦«}|std¦«‚t¦«}t |jj¦«}t||¦«}|std¦«‚|rK|D]H}t||¦«s6d  t|¦«¦«pd}td|›�¦«‚ŒItj d t|¦«›d
|›�¦« t|||¦«} n2#t$r%}
tjd |
›�¦«d d
icYd}
~
Sd}
~
wwxYwd | iS)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``。
r-rür0r1rrýr2r3u(_execute_sql_count_only 执行语å�¥æ•°=r5u&_execute_sql_count_only 执行失败: r8r=N)r>rr r
rËrdr:rrr3rr r:rErrQr;) rºr-rUr<rarÏrr=r>rÜr?s r7Ú_execute_sql_count_onlyrF§s¯€ð$ ˆ9�"×
Ò
Ñ
Ô
€CØ ð-ÝÐ+Ñ,Ô,Ð,å ˜Ñ 'Ô 'Ð -¨2×
4Ò
4Ñ
6Ô
6€CØ ð3ÝÐ1Ñ2Ô2Ð2å
‰\Œ\€FÝ/°´Ô0CÑDÔD€IÝ% c¨9Ñ5Ô5€Jà ð'ݘÑ&Ô&Ð&àðØð ð ˆBÝ# B¨ Ñ2Ô2ð
Ø—Y’YÕ4°YÑ?Ô?Ñ@Ô@ÐJÀF�Ý ØeÐacÐeÐeñôðð
õ „HÐ
]½¸J¹¼Ð
]Ð
]ÐS[Ð
]Ð
]Ñ^Ô^Ð^ðÝ .¨v°zÀ9Ñ MÔ MˆˆøÝ ðððÝ Œ Ð>¸1Ð>Ð>Ñ?Ô?Ð?ؘˆ}ÐÐÐÐÐÐøøøøðøøøð
�Qˆ<ÐsÄD+Ä+
EÄ5EÅEÅEr)rédÚ object_typeÚ
ObjectTyperÚ detail_levelÚ DetailLevelÚlimitúdict[str, Any]c
óþ‡)—|r|std¦«‚|r|dvrtd|›d�¦«‚tdtdt|¦«¦«¦«}|�|nd}t |¦«Š)t d ¦«pd
 ¦«}|std ¦«‚ t¦«} n/#t$r"}
tt|
¦«¦«|
‚d}
~
wwxYw t| ¦«} n<#t$r/}
tj d |
›�¦«td
|
›�¦«|
‚d}
~
wwxYw t|  ¦«¦«} n#t$rg} YnwxYwt!| ¦«}
|r4|| vr,d | ¦«pd}td|›d|›�¦«‚|g}n|
r|
ndg}| jj}g}|dkrª|
r|
n| }ˆ)fd„|D¦«}|D]‘}t)|¦«|krn{|dkr| d|i¦«Œ5 t|  |¬¦«¦«}n#t$rg}YnwxYw| |t)|¦«dœ¦«Œ’�né|dk�r¬|D�]¦}t)|¦«|kr�n� t|  |¬¦«¦«}n#t$rYŒJwxYw|D�]T}t)|¦«|kr�n=t/t|¦«¦«}‰) |¦«sŒK|dkr| ||dœ¦«Œj|dkrdt3| ||¦«}t5| ||¦«}t7| ||¦«}||t)|¦«|dœ}|r||d<| |¦«ŒÔt3| ||¦«}t9| ||¦«}t5| ||¦«}t7| ||¦«}||t)|¦«|d„|D¦«|dœ}|r||d<| |¦«�ŒV�Œ¨�n6|dv�r5|D�]0}t)|¦«|kr�n |rt;| ||¦«g}n d„|  |¬¦«D¦«}n#t$rYŒ\wxYw|D�]Ì}t)|¦«|kr�nµt/t|¦«¦«}|d kr·t3| ||¦«}|D]¢}t)|¦«|krnŒ‰) |d!¦«sŒ3|dkr | |d!||d"œ¦«ŒY|d!|||d#|d$d%k|d&d'œ} d(|vr |d(| d(<| | ¦«Œ£Œòt9| ||¦«}|D]Æ}!t)|¦«|krn°t|! d¦«pd
¦«}"‰) |"¦«sŒQ|dkr| |"||d"œ¦«Œq| |"|||! d)¦«|! d*¦«|! d+¦«d,œ¦«ŒÇ�ŒÎ�Œ2nü|d-vræ|d.krd/nd0}# t?| |||#¬1¦«}$n3#t$r&}
tj d2|›d3|
›�¦«g}$Yd}
~
nd}
~
wwxYw|$D]�\}%}&}'}(t)|¦«|krnu‰) |&¦«sŒ2|dkr| |&|%dœ¦«ŒQ|dkr| |&|%|'ddd4œ¦«Œs| |&|%|'ddd|(d5œ¦«Œ‘ntd6|›�¦«‚|||||t)|¦«|t)|¦«|kd7œS)8u
按对象类型在已�置的业务库中探索 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 共��定「�查这一张表或视图�上的列