schema.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. # -*- coding: utf-8 -*-
  2. from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
  3. from pydantic.alias_generators import to_camel
  4. class ImportFieldModel(BaseModel):
  5. model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
  6. base_column: str | None = Field(description='数据库字段名', default=None)
  7. excel_column: str | None = Field(description='excel字段名', default=None)
  8. default_value: str | None = Field(description='默认值', default=None)
  9. is_required: bool | None = Field(description='是否必传', default=None)
  10. selected: bool | None = Field(description='是否勾选', default=None)
  11. @model_validator(mode='before')
  12. @classmethod
  13. def _normalize(cls, data):
  14. if isinstance(data, dict):
  15. for key in ('base_column', 'excel_column', 'default_value'):
  16. val = data.get(key)
  17. if isinstance(val, str):
  18. val = val.strip()
  19. if val == '':
  20. val = None
  21. data[key] = val
  22. # is_required 兼容转换
  23. val = data.get('is_required')
  24. if isinstance(val, str):
  25. lowered = val.strip().lower()
  26. if lowered in {'true', '1', 'y', 'yes'}:
  27. data['is_required'] = True
  28. elif lowered in {'false', '0', 'n', 'no'}:
  29. data['is_required'] = False
  30. return data
  31. @model_validator(mode='after')
  32. def _validate(self):
  33. if self.selected and not (self.base_column and self.base_column.strip()):
  34. raise ValueError('选中字段必须提供数据库字段名')
  35. if self.is_required and not (self.excel_column and self.excel_column.strip()):
  36. raise ValueError('必传字段必须提供excel字段名')
  37. return self
  38. class ImportModel(BaseModel):
  39. model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
  40. table_name: str | None = Field(description='表名', default=None)
  41. sheet_name: str | None = Field(description='Sheet名', default=None)
  42. filed_info: list[ImportFieldModel] | None = Field(description='字段关联表', default=None)
  43. file_name: str | None = Field(description='文件名', default=None)
  44. @model_validator(mode='after')
  45. def _validate(self):
  46. # excel_column 不重复(忽略 None)
  47. if self.filed_info:
  48. seen = set()
  49. for f in self.filed_info:
  50. if f.excel_column:
  51. key = f.excel_column.strip()
  52. if key in seen:
  53. raise ValueError('excel字段名存在重复')
  54. seen.add(key)
  55. return self