6565 Termbase ,
6666)
6767from knowledge .services .document_strategy import normalize_document_strategy
68- from knowledge .services .knowledge_sync_schedule import remove_knowledge_sync_job
68+ from knowledge .services .knowledge_archive import (
69+ ARCHIVE_VERSION ,
70+ export_resources ,
71+ portable_knowledge_meta ,
72+ restore_resources ,
73+ validate_archive ,
74+ )
75+ from knowledge .services .knowledge_sync_schedule import deploy_knowledge_sync_job , remove_knowledge_sync_job
6976from knowledge .services .multimodal_retrieval import (
7077 MAX_QUERY_IMAGE_COUNT ,
7178 get_hit_asset_map ,
@@ -664,6 +671,7 @@ def export_knowledge(self, with_source_file=False, with_valid=True):
664671 QuerySet (File ).filter (source_id__in = document_id_list , source_type = FileSourceType .DOCUMENT )
665672 )
666673 source_file_map = {str (source_file .source_id ): source_file for source_file in source_file_list }
674+ source_files_by_id = {str (source_file .id ): source_file for source_file in source_file_list }
667675
668676 # 查询标签和文档标签关联
669677 tag_list = list (QuerySet (Tag ).filter (knowledge_id = knowledge_id ).values ("id" , "key" , "value" ))
@@ -685,7 +693,9 @@ def export_knowledge(self, with_source_file=False, with_valid=True):
685693 for doc in document_list :
686694 if with_source_file :
687695 doc .meta = {** doc .meta } if doc .meta else {}
688- source_file = source_file_map .get (str (doc .id ))
696+ source_file = source_files_by_id .get (str (doc .meta .get ("source_file_id" ))) or source_file_map .get (
697+ str (doc .id )
698+ )
689699 if source_file :
690700 doc .meta ["source_file_id" ] = str (source_file .id )
691701 else :
@@ -747,15 +757,21 @@ def export_knowledge(self, with_source_file=False, with_valid=True):
747757 f .write (source_file .get_bytes ())
748758
749759 knowledge_json = {
760+ "archive_version" : ARCHIVE_VERSION ,
761+ "source_knowledge_id" : str (knowledge .id ),
750762 "name" : knowledge .name ,
751763 "desc" : knowledge .desc ,
752764 "type" : knowledge .type ,
753- "meta" : {} if knowledge .type == KnowledgeType .LARK else (knowledge .meta if knowledge .meta else {}),
765+ "meta" : portable_knowledge_meta (knowledge ),
766+ "external_service" : knowledge .external_service ,
754767 "file_size_limit" : knowledge .file_size_limit ,
755768 "file_count_limit" : knowledge .file_count_limit ,
756769 "tags" : [{"key" : t ["key" ], "value" : t ["value" ]} for t in tag_list ],
757770 "termbase" : terms ,
758771 "source_file_list" : source_file_export_list ,
772+ "resources" : export_resources (
773+ knowledge , document_list , source_file_list , tempdir , source_file_export_list
774+ ),
759775 }
760776
761777 with open (os .path .join (tempdir , "knowledge.json" ), "w" , encoding = "utf-8" ) as f :
@@ -954,6 +970,7 @@ def import_knowledge(self, file, is_import_tool=False, with_valid=True):
954970
955971 # knowledge.json -> knowledge
956972 knowledge_data = json .loads (zf .read ("knowledge.json" ))
973+ resources = validate_archive (knowledge_data , zf )
957974 source_file_meta_map = {
958975 str (source_file .get ("id" )): source_file
959976 for source_file in knowledge_data .get ("source_file_list" , [])
@@ -981,12 +998,20 @@ def import_knowledge(self, file, is_import_tool=False, with_valid=True):
981998 user_id = user_id ,
982999 workspace_id = workspace_id ,
9831000 folder_id = folder_id ,
1001+ ** (
1002+ {"external_service" : knowledge_data ["external_service" ]}
1003+ if "external_service" in knowledge_data
1004+ else {}
1005+ ),
9841006 )
9851007 knowledge .save ()
9861008
1009+ if resources is not None :
1010+ restore_resources (knowledge , knowledge_data , zf )
1011+
9871012 # 图片
9881013 old_to_new_file_map = {}
989- for name in namelist :
1014+ for name in namelist if resources is None else [] :
9901015 if name .startswith ("oss/file/" ) and name != "oss/file/" :
9911016 old_id = name .split ("/" )[- 1 ]
9921017 if not old_id :
@@ -1003,15 +1028,17 @@ def import_knowledge(self, file, is_import_tool=False, with_valid=True):
10031028 old_to_new_file_map [old_id ] = str (new_file .id )
10041029
10051030 # knowledge.xlsx -> doc + para + problem
1006- xlsx_bytes = io .BytesIO (zf .read ("knowledge.xlsx" ))
1007- workbook = openpyxl .load_workbook (xlsx_bytes )
1031+ sheets = []
1032+ if resources is None :
1033+ xlsx_bytes = io .BytesIO (zf .read ("knowledge.xlsx" ))
1034+ sheets = openpyxl .load_workbook (xlsx_bytes ).worksheets
10081035
10091036 document_model_list = []
10101037 paragraph_model_list = []
10111038 problem_paragraph_object_list = []
10121039 doc_tags_map = {}
10131040
1014- for sheet in workbook . worksheets :
1041+ for sheet in sheets :
10151042 doc_name = sheet .title
10161043 rows = list (sheet .iter_rows (min_row = 2 , values_only = True ))
10171044 if not rows :
@@ -1112,14 +1139,15 @@ def import_knowledge(self, file, is_import_tool=False, with_valid=True):
11121139 QuerySet (Paragraph ).bulk_create (paragraph_model_list ) if len (paragraph_model_list ) > 0 else None
11131140
11141141 # 问题
1115- problem_model_list , problem_paragraph_mapping_list = ProblemParagraphManage (
1116- problem_paragraph_object_list , knowledge_id
1117- ).to_problem_model_list ()
1118- bulk_create_in_batches (Problem , problem_model_list , batch_size = 1000 )
1119- bulk_create_in_batches (ProblemParagraphMapping , problem_paragraph_mapping_list , batch_size = 1000 )
1142+ if resources is None :
1143+ problem_model_list , problem_paragraph_mapping_list = ProblemParagraphManage (
1144+ problem_paragraph_object_list , knowledge_id
1145+ ).to_problem_model_list ()
1146+ bulk_create_in_batches (Problem , problem_model_list , batch_size = 1000 )
1147+ bulk_create_in_batches (ProblemParagraphMapping , problem_paragraph_mapping_list , batch_size = 1000 )
11201148
11211149 # Tag
1122- tag_list = knowledge_data .get ("tags" , [])
1150+ tag_list = knowledge_data .get ("tags" , []) if resources is None else []
11231151 if tag_list :
11241152 tag_model_list = []
11251153 tag_key_value_to_model = {}
@@ -1170,6 +1198,9 @@ def import_knowledge(self, file, is_import_tool=False, with_valid=True):
11701198
11711199 update_resource_mapping_by_knowledge (str (knowledge_id ))
11721200
1201+ if (knowledge .meta .get ("sync_setting" ) or {}).get ("enabled" ):
1202+ transaction .on_commit (partial (deploy_knowledge_sync_job , str (knowledge_id )), robust = True )
1203+
11731204 zf .close ()
11741205 return {"knowledge_id" : str (knowledge_id ), "type" : knowledge .type }
11751206
0 commit comments