33from __future__ import annotations
44
55from collections .abc import Callable
6- from dataclasses import dataclass
6+ from dataclasses import dataclass , field
77from enum import StrEnum
88from typing import TYPE_CHECKING , Self
99
1515from excelalchemy .helper .pydantic import get_model_field_names
1616from excelalchemy .i18n .messages import MessageKey
1717from excelalchemy .i18n .messages import message as msg
18- from excelalchemy .util .convertor import export_data_converter , import_data_converter
18+ from excelalchemy .util .converter import export_data_converter , import_data_converter
1919
2020if TYPE_CHECKING :
2121 from minio import Minio
@@ -34,10 +34,67 @@ class ImportMode(StrEnum):
3434 CREATE_OR_UPDATE = 'CREATE_OR_UPDATE'
3535
3636
37+ @dataclass (slots = True , frozen = True )
38+ class StorageOptions :
39+ """Normalized storage backend settings shared by importer and exporter configs."""
40+
41+ storage : ExcelStorage | None
42+ minio : Minio | None
43+ bucket_name : str
44+ url_expires : int
45+
46+ @property
47+ def has_explicit_storage (self ) -> bool :
48+ return self .storage is not None
49+
50+ @property
51+ def has_legacy_minio (self ) -> bool :
52+ return self .minio is not None
53+
54+
55+ @dataclass (slots = True , frozen = True )
56+ class ImporterSchemaOptions [ImportCreateModelT : BaseModel , ImportUpdateModelT : BaseModel ]:
57+ """Schema declaration and workbook presentation settings for imports."""
58+
59+ create_importer_model : type [ImportCreateModelT ] | None
60+ update_importer_model : type [ImportUpdateModelT ] | None
61+ sheet_name : str
62+ locale : str
63+
64+
65+ @dataclass (slots = True , frozen = True )
66+ class ImportBehavior [ContextT ]:
67+ """Execution callbacks and import workflow policy."""
68+
69+ data_converter : DataConverter | None
70+ creator : DmlCallback [ContextT ] | None
71+ updater : DmlCallback [ContextT ] | None
72+ context : ImportContext [ContextT ]
73+ is_data_exist : ExistenceCheckCallback [ContextT ] | None
74+ exec_formatter : Callable [[Exception ], str ]
75+ import_mode : ImportMode
76+
77+
78+ @dataclass (slots = True , frozen = True )
79+ class ExporterSchemaOptions [ExportModelT : BaseModel ]:
80+ """Schema declaration and workbook presentation settings for exports."""
81+
82+ exporter_model : type [ExportModelT ]
83+ sheet_name : str
84+ locale : str
85+
86+
87+ @dataclass (slots = True , frozen = True )
88+ class ExportBehavior :
89+ """Execution behavior used when rendering export rows."""
90+
91+ data_converter : DataConverter | None
92+
93+
3794@dataclass (slots = True )
38- class ImporterConfig [ContextT , ImporterCreateModelT : BaseModel , ImporterUpdateModelT : BaseModel ]:
39- create_importer_model : type [ImporterCreateModelT ] | None = None
40- update_importer_model : type [ImporterUpdateModelT ] | None = None
95+ class ImporterConfig [ContextT , ImportCreateModelT : BaseModel , ImportUpdateModelT : BaseModel ]:
96+ create_importer_model : type [ImportCreateModelT ] | None = None
97+ update_importer_model : type [ImportUpdateModelT ] | None = None
4198
4299 # The converter receives schema keys rather than workbook labels.
43100 data_converter : DataConverter | None = import_data_converter
@@ -57,6 +114,11 @@ class ImporterConfig[ContextT, ImporterCreateModelT: BaseModel, ImporterUpdateMo
57114 locale : str = 'zh-CN'
58115
59116 sheet_name : str = 'Sheet1'
117+ schema_options : ImporterSchemaOptions [ImportCreateModelT , ImportUpdateModelT ] = field (
118+ init = False , repr = False
119+ )
120+ behavior : ImportBehavior [ContextT ] = field (init = False , repr = False )
121+ storage_options : StorageOptions = field (init = False , repr = False )
60122
61123 def validate_model (self ) -> Self :
62124 if self .import_mode not in ImportMode .__members__ .values ():
@@ -100,11 +162,32 @@ def _validate_create_or_update(self) -> None:
100162
101163 def __post_init__ (self ) -> None :
102164 self .validate_model ()
165+ self .schema_options = ImporterSchemaOptions (
166+ create_importer_model = self .create_importer_model ,
167+ update_importer_model = self .update_importer_model ,
168+ sheet_name = self .sheet_name ,
169+ locale = self .locale ,
170+ )
171+ self .behavior = ImportBehavior (
172+ data_converter = self .data_converter ,
173+ creator = self .creator ,
174+ updater = self .updater ,
175+ context = self .context ,
176+ is_data_exist = self .is_data_exist ,
177+ exec_formatter = self .exec_formatter ,
178+ import_mode = self .import_mode ,
179+ )
180+ self .storage_options = StorageOptions (
181+ storage = self .storage ,
182+ minio = self .minio ,
183+ bucket_name = self .bucket_name ,
184+ url_expires = self .url_expires ,
185+ )
103186
104187
105188@dataclass (slots = True )
106- class ExporterConfig [ExporterModelT : BaseModel ]:
107- exporter_model : type [ExporterModelT ]
189+ class ExporterConfig [ExportModelT : BaseModel ]:
190+ exporter_model : type [ExportModelT ]
108191 # The converter receives schema keys rather than workbook labels.
109192 data_converter : DataConverter | None = export_data_converter
110193
@@ -115,6 +198,9 @@ class ExporterConfig[ExporterModelT: BaseModel]:
115198 locale : str = 'zh-CN'
116199
117200 sheet_name : str = 'Sheet1'
201+ schema_options : ExporterSchemaOptions [ExportModelT ] = field (init = False , repr = False )
202+ behavior : ExportBehavior = field (init = False , repr = False )
203+ storage_options : StorageOptions = field (init = False , repr = False )
118204
119205 def validate_model (self ) -> Self :
120206 if not self .exporter_model :
@@ -123,3 +209,15 @@ def validate_model(self) -> Self:
123209
124210 def __post_init__ (self ) -> None :
125211 self .validate_model ()
212+ self .schema_options = ExporterSchemaOptions (
213+ exporter_model = self .exporter_model ,
214+ sheet_name = self .sheet_name ,
215+ locale = self .locale ,
216+ )
217+ self .behavior = ExportBehavior (data_converter = self .data_converter )
218+ self .storage_options = StorageOptions (
219+ storage = self .storage ,
220+ minio = self .minio ,
221+ bucket_name = self .bucket_name ,
222+ url_expires = self .url_expires ,
223+ )
0 commit comments