
    l'hQK                         S r SSKrSSKrSSKJrJrJrJr  SSK	r	SSK
r
SSKJr  SSKr\	R                  " \5      r " S S5      rg)u   
エラーレポート生成モジュール
データベースのテーブル定義を取得し、エラー情報と組み合わせて
詳細なエラーレポートを生成する
    N)DictListAnyOptional)datetimec            	       .   \ rS rSrSrS\R                  R                  4S jrS\	\
\	\
\
4   4   4S jrS\
S\R                  4S jrS	\
S\	\
\
4   4S
 jrS\
S\
S\	\
\4   4S jr S!S\\	   S\R                  S\R                  S\R                  4S jjr S!S\
S\
S\R                  S\
4S jjrS\
S\
4S jrS\	S\	S\S\
4S jr  S"S\R                  S\
S\
S\
4S jjrS\
S\R                  SS4S jrS\R                  S\R                  4S jrS rg)#ErrorReportGenerator   u$   エラーレポート生成クラスdb_connectionc                 H    Xl         0 U l        U R                  5       U l        g)u>   
初期化

Args:
    db_connection: データベース接続
N)
connectiontable_definitions_init_error_analysis_ruleserror_analysis_rules)selfr   s     /app/error_report_generator.py__init__ErrorReportGenerator.__init__   s"     (!#$($C$C$E!    returnc                 :    SSSS.SSSS.SS	S
S.SS	S
S.SSSS.S.$ )u$   エラー分析ルールを初期化z&Data too long for column '(.+)' at rowuE   カラムのサイズを拡張するか、データを切り詰める   データ長超過)pattern   対処方法   エラータイプzDuplicate entry '(.+)' for keyuE   重複チェックを追加するか、既存データを更新する   重複エラーz*Incorrect integer value: '(.+)' for columnu!   数値変換処理を追加する   型変換エラーz*Incorrect decimal value: '(.+)' for columnzColumn '(.+)' cannot be nullu4   NULL値のチェックとデフォルト値の設定u   NULL制約違反)zData too longzDuplicate entryzIncorrect integer valuezIncorrect decimal valuezcannot be null )r   s    r   r   /ErrorReportGenerator._init_error_analysis_rules   s_     E g&: = g&7  I C&:( I C&:( ; V&8+
 	
r   
table_namec                 :   XR                   ;   a  U R                   U   $ SnU R                  R                  5        nUR                  X!45        UR	                  5       nSSS5        [
        R                  " W5      nXPR                   U'   U$ ! , (       d  f       N4= f)uu   
テーブル定義を取得

Args:
    table_name: テーブル名
    
Returns:
    テーブル定義のDataFrame
a  
        SELECT 
            COLUMN_NAME,
            DATA_TYPE,
            COLUMN_TYPE,
            IS_NULLABLE,
            COLUMN_DEFAULT,
            CHARACTER_MAXIMUM_LENGTH,
            NUMERIC_PRECISION,
            NUMERIC_SCALE,
            COLUMN_COMMENT
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = DATABASE()
          AND TABLE_NAME = %s
        ORDER BY ORDINAL_POSITION
        N)r   r   cursorexecutefetchallpd	DataFrame)r   r    queryr"   columnsdfs         r   get_table_definition)ErrorReportGenerator.get_table_definition<   s     ///))*55" __##%NN5-0oo'G & \\'"-/z*	 &%s   #B
Berror_messagec                 $   SSUS.nU R                   R                  5        Hk  u  p4X1;   d  M  [        R                  " US   U5      nU(       d  M/  US   US'   US   US'   UR	                  5       (       a  UR                  S5      OUUS'     U$    U$ )	u~   
エラーメッセージを分析

Args:
    error_message: エラーメッセージ
    
Returns:
    分析結果の辞書
   不明u*   エラー内容を確認してくださいr   r      エラー詳細r   r   r      r0   )r   itemsresearchgroupsgroup)r   r,   result
error_typerulematchs         r   analyze_error"ErrorReportGenerator.analyze_errorb   s     #+H,
 !% 9 9 ? ? AJ*		$y/=A5378L3MF/0-1.-AF>*BG,,..AVcF,- !B r   column_namec                     U R                  U5      nX3S   U:H     nUR                  (       a  SSS.$ UR                  S   nUS   US   (       a  US   S.$ SS.$ )u   
カラム情報を取得

Args:
    table_name: テーブル名
    column_name: カラム名
    
Returns:
    カラム情報の辞書
COLUMN_NAMEr.   )   型   コメントr   COLUMN_TYPECOLUMN_COMMENT )r*   emptyiloc)r   r    r=   r)   
column_rowrows         r   get_column_info$ErrorReportGenerator.get_column_info}   s     &&z2=)[89
 ( 
 ooa }%589I5JC 01
 	
PR
 	
r   N
error_logstransplant_df
mapping_dfc                    / nU(       dU  UR                  SSSSSSSS[        R                  " 5       R                  S5      SSS	.5        [        R
                  " U5      $ [        US
5       GHc  u  pVUR                  SS5      nUR                  SUR                  SS5      5      nUR                  SUR                  SS5      5      n	UR                  SUR                  SS5      5      n
UR                  SS5      nUR                  SUR                  SS5      5      nUR                  SUR                  SS5      5      nUR                  SS5      nUR                  SS5      nUR                  SS5      nUR                  S[        R                  " 5       R                  S5      5      nU(       a  U	(       a  U R                  X5      O0 nU(       a  U R                  U5      OUS:X  a  SOSS U=(       d    US!.nU(       a  UOU R                  XU5      nU R                  UUU5      nUS:X  a  SOSn0 S"U_S#U_S$U=(       d    S%_S&U_S'U R                  U5      _S(U	_S)U_S*U	_S+UR                  S+S5      _S,UR                  S,S5      _S-U
_S.U(       a  UOS_S/U_S0U(       a  UOS_SU_S1US1   _S2U_S3US4   UUS5.EnUR                  U5        GMf     [        R
                  " U5      $ )6uF  
エラーレポートを生成（統一フォーマット対応）

Args:
    error_logs: エラー/警告ログのリスト（統一フォーマット）
    transplant_df: 移植データのDataFrame
    mapping_df: マッピング情報のDataFrame（オプション）
    
Returns:
    エラーレポートのDataFrame
-u   エラーなしu   正常終了u$   処理は正常に完了しましたu   対処不要z%Y-%m-%d %H:%M:%S   情報u   なし)u   エラー番号YearNo   テーブル名   カラム名r      エラー内容	   元の値r      発生日時	   重要度u	   影響度r1   levelERRORtablerR   rD   columnu   更新カラム名year_norQ   seitai_isyoku_idmessagerT   original_valueu   値expected_value
csv_sourceerror_detail	timestampWARNINGu   警告u	   エラーu!   詳細を確認してくださいr/   NO	   レベルCSVu   項目名（移植時）u   CSVカラムu   テーブルrS      テーブル物理名u   物理カラム名r@   rA   u   移植登録ID(YearNo)u   生体移植IDrU   u	   期待値r0   r   u	   未対応r   )u   対応状況r   rW   rV   )appendr   nowstrftimer%   r&   	enumerategetrI   r;   _find_csv_column_suggest_action_get_table_japanese_name)r   rK   rL   rM   report_dataidx	log_entryrX   r    r=   r\   r]   r^   r_   r`   ra   rb   rc   column_infoerror_analysis
csv_columnactionseverity
report_rows                           r   generate_error_report*ErrorReportGenerator.generate_error_report   sK     #&#4 #&4#I  . ( 7 78K L%%   <<,,'
A6NCMM'73E"w	>OQS0TUJ#--)--@TVX2YZKmmIy}}Xr/JKG(}}-?DmmIy}}=NPR/STG&]]+;Y]]5RT=UVN&]]+;R@N"|R8J$==<L!k8<<>3J3JK^3_`I LVZe$..zGkmK =DT//82792Dh+ C#/#:7JN (2t7L7LZfp7qJ )).+~VF $)I#5x;HcU z?%? 
	
  = =j I  ( %k {ub1  C )' !6F"2C ^ ~^3 "7  ">2C#D!" #$ !,&45I&J% )+J0 z*s 7v ||K((r   c                 .    Ub  UR                   (       a  gg)u   
マッピング情報からCSVカラム名を検索

Args:
    table_name: テーブル名
    column_name: カラム名
    mapping_df: マッピング情報
    
Returns:
    CSVカラム名
r.   )rE   )r   r    r=   rM   s       r   rn   %ErrorReportGenerator._find_csv_column   s     !1!1 r   c                 >    SSSSSSSSS	S
S.
nUR                  X5      $ )u$   テーブルの日本語名を取得u!   移植基本情報(共通-生体)u   ドナー情報(共通-生体)u   ドナー情報(腎-生体)u   移植基本情報(腎-生体)u   生活状況D(生体-ドナー)u(   検査項目R(生体-レシピエント)u   検査項目D(生体-ドナー)u%   合併症R(生体-レシピエント)u4   維持期免疫抑制薬R(生体-レシピエント)u%   感染症R(生体-レシピエント))
T_ISHOKU_KIHON_LIVT_DONOR_LIVT_DONOR_KIDNEY_LIVT_ISHOKU_KIHON_KIDNEY_LIVT_LIVING_D_LIVT_KENSA_R_LIVT_KENSA_D_LIVT_GAPPEI_R_LIVT_IJI_MENEKI_YOKUSEI_R_LIVT_KANSEN_R_LIV)rm   )r   r    table_name_maps      r   rp   -ErrorReportGenerator._get_table_japanese_name	  s=     #F;"?)I?G>E*`E
 !!*99r   ru   rt   
error_datac                    US   nUR                  SS5      nUS:X  a  SU;   aa  [        R                  " SU5      nU(       a=  [        UR	                  S5      5      n[        [        U5      5      nSU S	US
-    SU S3$  US   $ SU;   a"  [        U[        [        45      (       a  US:  a  gUS   $ US:X  a  SU;   d  SU;   a  gUS   $ US:X  a  gUS   $ )u   
エラーに応じた具体的な対処方法を提案

Args:
    error_analysis: エラー分析結果
    column_info: カラム情報
    error_data: エラーデータ
    
Returns:
    対処方法の提案
r   r@   rD   r   varcharzvarchar\((\d+)\)r1   zvarchar(u   )をvarchar(
   u"   )に拡張するか、データをu   文字に切り詰めるtinyint   u-   tinyintをsmallintまたはintに変更するr   r   intdecimalu9   数値以外の文字を除去する変換処理を追加r   uR   INSERT前に存在チェックを追加し、既存の場合はUPDATEまたはSKIP)	rm   r3   r4   r   r6   lenstr
isinstancefloat)	r   ru   rt   r   r8   column_typer:   current_lengthrequired_lengths	            r   ro   $ErrorReportGenerator._suggest_action  s    $$89
!ooeR0--K'		"5{C%(Q%8N&)#j/&:O%n%5\/TVBVAWWy  {I  zJ  Jb  c  c  ".11 k)jc5\.R.R#J!.11//#yK'?R!.11,,gn--r   	report_df
output_dirrange_suffixc                 n   [         R                  " USS9  [        R                  " 5       R	                  S5      n[         R
                  R                  USU U S35      n[        R                  " USS9 nSUR                  ;   a  XS   S	:H     nUR                  (       d$  UR                  US
SS9  U R                  US
U5        XS   S:H     nUR                  (       d$  UR                  USSS9  U R                  USU5        UR                  USSS9  U R                  USU5        O$UR                  USSS9  U R                  USU5        SSS5        [         R
                  R                  USU U S35      n	UR                  U	SSS9  [        R                  SU 35        U$ ! , (       d  f       N_= f)u8  
エラーレポートを保存（ERROR/WARNING別シート対応）

Args:
    report_df: エラーレポートのDataFrame
    output_dir: 出力ディレクトリ
    range_suffix: ファイル名に追加する範囲サフィックス（分割実行対応）
    
Returns:
    保存したファイルパス
T)exist_okz%Y%m%d_%H%M%Serror_report_z.xlsxopenpyxl)enginerf   rY   u   エラー一覧F)
sheet_nameindexrd   u   警告一覧u   全件一覧u   エラーレポートNz.csvz	utf-8-sig)r   encodingu,   エラーレポートを保存しました: )osmakedirsr   rj   rk   pathjoinr%   ExcelWriterr(   rE   to_excel_adjust_column_widthto_csvloggerinfo)
r   r   r   r   rc   
excel_pathwritererror_df
warning_dfcsv_paths
             r   save_error_report&ErrorReportGenerator.save_error_report?  s    	J.LLN++O<	 WW\\*i[V[.\]
^^Jz:f i///${%;w%FG~~%%f9JRW%X--f6GR ''='JK
!''''>QV'W--fnjQ ""6nE"R))&.)L ""66MUZ"[))&2I9U- ;2 77<<
mI;|nTX,YZEB:,OP= ;:s   5CF&&
F4r   r)   c                    X!R                   ;   a  UR                   U   nU H  n [        X5   R                  [        5      R	                  [
        5      R                  5       [        U5      5      nUR                  R                  U5      n[        US-   S5      UR                  [        SU-   5         l        M     gg! [         a     M  f = f)u   列幅を自動調整   2   A   N)sheetsmaxastyper   mapr   r(   get_locmincolumn_dimensionschrwidth	Exception)r   r   r   r)   	worksheetr[   column_lengthcol_idxs           r   r   )ErrorReportGenerator._adjust_column_widthr  s    &j1I$'
(9(9#(>(B(B3(G(K(K(MsSY{$[M jj008GKN}_`O`bdKeI//BL0ABH	  ' ! s   BB>>
CCc                    / nSUR                   ;   aQ  UR                  S5      R                  5       R                  SS9nSUS'   UR	                  UR                  SS0S95        SUR                   ;   aj  S	UR                   ;   aZ  UR                  SS	/5      R                  5       R                  SS9nS
US'   US   S-   US	   -   US'   UR	                  U/ SQ   5        S	UR                   ;   a^  UR                  S	5      R                  SS S.5      R                  5       n/ SQUl         SUS'   US	   US'   UR	                  U/ SQ   5        U(       a;  [        R                  " USS9n/ SQnU H  nXR                   ;  d  M  SXh'   M     Xg   $ S	UR                   ;   a=  UR                  S	5      R                  SS S.5      R                  5       n/ SQUl         U$ [        R                  " S/S/S/S/S.5      $ )u   
エラーサマリーレポートを生成（統一フォーマット対応）

Args:
    report_df: エラーレポートのDataFrame
    
Returns:
    サマリーレポートのDataFrame
rf      件数)nameu   レベル別   分類   項目)r(   rh   r   u   テーブル別z - )r   r   r   countc                 ^    [        U 5      S:  a  U R                  5       R                  S   $ S$ Nr   rD   r   value_countsr   xs    r   <lambda>>ErrorReportGenerator.generate_summary_report.<locals>.<lambda>  s*    s1vPQz!..*:*@*@*C*YWY*Yr   )re   r   )r   r      主な対処方法u   エラータイプ別)r   r   r   r   T)ignore_indexrO   c                 ^    [        U 5      S:  a  U R                  5       R                  S   $ S$ r   r   r   s    r   r   r     s*    3q6TU:ann.>.D.DQ.G.][].]r   rP   u   データなしr   )
r(   groupbysizereset_indexri   renameaggr%   concatr&   )	r   r   summary_datalevel_summarytable_summaryerror_type_summaryfinal_summaryrequired_columnscols	            r   generate_summary_report,ErrorReportGenerator.generate_summary_report  sN     )+++%--k:??AMMS[M\M&4M(# 4 4k8=T 4 UV #i&7&77<PT]TeTe<e%--/FH\.]^cceqqwq  AM&7M(#&34K&Lu&TWdeyWz&zM(#.L MN  9#4#44!*!2!23G!H!L!L YN " {}  *`&+Bx(+=>R+Sx( 23g hi IIlFMS'333),M& ( !22 $y'8'88%.%6%67K%L%P%P!$]R & ;= # .d"*))||zFWEXefdg  AD  @E  %F  G  Gr   )r   r   r   )N)z./logsrD   )__name__
__module____qualname____firstlineno____doc__pymysqlconnections
Connectionr   r   r   r   r%   r&   r*   r;   r   rI   r   rz   rn   rp   ro   r   r   r   __static_attributes__r   r   r   r	   r	      s   .	Fg&9&9&D&D 	F
Dd38n1D,E 
<$s $r|| $L3 4S> 6
# 
C 
DcN 
8 8<\)T
 \)+-<<\)(*\)@B\)~ 483 S $&LL<?(:3 :3 : $.d $. $.SV $.[^ $.L LT-/12<< 1S 1'*1471fs  QU 7G 7G",, 7Gr   r	   )r   pandasr%   r   typingr   r   r   r   loggingr3   r   r   	getLoggerr   r   r	   r   r   r   <module>r      sB   
   , ,  	  				8	$fG fGr   