models.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. """
  2. 数据模型定义模块
  3. 定义AI换脸换装系统的所有数据表结构
  4. 用户表:存储用户信息(用户ID,用户名, 密码哈希,是否激活,是否管理员,创建时间,更新时间,最后登录时间)
  5. 图片记录表:存储图片信息(图片ID,用户ID,图片类型,原始文件名,存储路径,文件大小,图片哈希,是否已删除,创建时间,更新时间)
  6. 处理记录表:存储处理记录信息(处理记录ID,用户ID,人脸图片ID,服装图片ID,生成结果图片ID, AI生成的文案内容,完成时间)
  7. 系统配置表:存储系统配置信息(配置ID,配置键,配置值,配置类型,配置描述,是否公开配置,创建时间,更新时间)
  8. 数据库版本表:存储数据库版本信息(版本ID,版本号,版本描述,应用时间,迁移文件名)
  9. """
  10. from datetime import datetime
  11. from typing import Optional, List
  12. from sqlalchemy import (
  13. Column, Integer, String, Text, DateTime, Boolean,
  14. Float, ForeignKey, Index, UniqueConstraint, CheckConstraint
  15. )
  16. from sqlalchemy.ext.declarative import declarative_base
  17. from sqlalchemy.orm import relationship, Mapped
  18. from sqlalchemy.sql import func
  19. # 定义数据库模型
  20. Base = declarative_base()
  21. class User(Base):
  22. """用户表"""
  23. __tablename__ = "users"
  24. id = Column(Integer, primary_key=True, autoincrement=True, comment="用户ID")
  25. username = Column(String(50), unique=True, nullable=False, comment="用户名")
  26. password_hash = Column(String(255), nullable=False, comment="密码哈希")
  27. is_active = Column(Boolean, default=True, comment="是否激活")
  28. is_admin = Column(Boolean, default=False, comment="是否管理员")
  29. created_at = Column(DateTime, default=func.now(), comment="创建时间")
  30. updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
  31. last_login = Column(DateTime, nullable=True, comment="最后登录时间")
  32. # 关联关系: 用户与图片记录、处理记录一对多关系(一个用户可以有多张图片和多个处理记录)
  33. image_records: Mapped[List["ImageRecord"]] = relationship("ImageRecord", back_populates="user")
  34. process_records: Mapped[List["ProcessRecord"]] = relationship("ProcessRecord", back_populates="user")
  35. text_records: Mapped[List["TextRecord"]] = relationship("TextRecord", back_populates="user")
  36. __table_args__ = (
  37. Index('idx_username', 'username'),
  38. )
  39. class ImageRecord(Base):
  40. """图片记录表"""
  41. __tablename__ = "image_records"
  42. id = Column(Integer, primary_key=True, autoincrement=True, comment="图片记录ID")
  43. user_id = Column(Integer, ForeignKey("users.id"), nullable=False, comment="用户ID")
  44. image_type = Column(String(20), nullable=False, comment="图片类型(face/cloth/result/original)")
  45. original_filename = Column(String(255), nullable=False, comment="原始文件名")
  46. stored_path = Column(String(500), nullable=False, comment="存储路径")
  47. file_size = Column(Integer, nullable=True, comment="文件大小(字节)")
  48. image_hash = Column(String(64), nullable=True, comment="图片哈希值")
  49. is_deleted = Column(Boolean, default=False, comment="是否已删除")
  50. created_at = Column(DateTime, default=func.now(), comment="创建时间")
  51. updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
  52. # 关联关系:图片记录与用户、处理记录多对一关系;一个人脸图片可以有多个处理记录
  53. user: Mapped["User"] = relationship("User", back_populates="image_records")
  54. face_processes: Mapped[List["ProcessRecord"]] = relationship(
  55. "ProcessRecord",
  56. foreign_keys="ProcessRecord.face_image_id",
  57. back_populates="face_image"
  58. )
  59. cloth_processes: Mapped[List["ProcessRecord"]] = relationship(
  60. "ProcessRecord",
  61. foreign_keys="ProcessRecord.cloth_image_id",
  62. back_populates="cloth_image"
  63. )
  64. result_processes: Mapped[List["ProcessRecord"]] = relationship(
  65. "ProcessRecord",
  66. foreign_keys="ProcessRecord.result_image_id",
  67. back_populates="result_image"
  68. )
  69. __table_args__ = (
  70. Index('idx_image_user_id', 'user_id'),
  71. Index('idx_image_type', 'image_type'),
  72. Index('idx_image_created_at', 'created_at'),
  73. CheckConstraint("image_type IN ('face', 'cloth', 'result', 'original')", name="ck_image_type"),
  74. )
  75. class TextRecord(Base):
  76. """文本模板记录表"""
  77. __tablename__ = "text_records"
  78. id = Column(Integer, primary_key=True, autoincrement=True, comment="文本模板记录ID")
  79. user_id = Column(Integer, ForeignKey("users.id"), nullable=False, comment="用户ID")
  80. text_type = Column(String(20), nullable=False, comment="文本模型类型(prompt/copywrite)")
  81. text_name = Column(String(20), nullable=False, comment="文本名称")
  82. text_label = Column(String(20), nullable=False, comment="文本模板标签")
  83. text_content = Column(Text, nullable=False, comment="文本模板内容")
  84. created_at = Column(DateTime, default=func.now(), comment="创建时间")
  85. # 关联关系:文本模型与用户多对一关系
  86. user: Mapped["User"] = relationship("User", back_populates="text_records")
  87. __table_args__ = (
  88. Index('idx_text_user_id', 'user_id'),
  89. Index('idx_text_type', 'text_type'),
  90. Index('idx_text_name', 'text_name'),
  91. Index('idx_text_label', 'text_label'),
  92. CheckConstraint("text_type IN ('prompt', 'copywrite')", name="ck_text_type"),
  93. )
  94. class ProcessRecord(Base):
  95. """AI换脸换装处理记录表"""
  96. __tablename__ = "process_records"
  97. id = Column(Integer, primary_key=True, autoincrement=True, comment="处理记录ID")
  98. user_id = Column(Integer, ForeignKey("users.id"), nullable=False, comment="用户ID")
  99. # 输入图片信息
  100. face_image_id = Column(Integer, ForeignKey("image_records.id"), nullable=False, comment="人脸图片ID")
  101. cloth_image_id = Column(Integer, ForeignKey("image_records.id"), nullable=False, comment="服装图片ID")
  102. # 输出图片信息
  103. result_image_id = Column(Integer, ForeignKey("image_records.id"), nullable=True, comment="生成结果图片ID")
  104. # 文案信息
  105. generated_text = Column(Text, nullable=True, comment="AI生成的文案内容")
  106. # 状态信息
  107. status = Column(String(20), nullable=False, default="待审核", comment="处理记录状态")
  108. # 完成时间
  109. completed_at = Column(DateTime, nullable=True, onupdate=func.now(), comment="完成时间")
  110. # 任务类型
  111. task_type = Column(String(40), nullable=False, comment="任务类型")
  112. # 提示词
  113. prompt = Column(Text, nullable=False, comment="提示词")
  114. # 关联关系:处理记录与用户、图片记录多对一关系
  115. user: Mapped["User"] = relationship("User", back_populates="process_records")
  116. face_image: Mapped["ImageRecord"] = relationship(
  117. "ImageRecord",
  118. foreign_keys=[face_image_id],
  119. back_populates="face_processes"
  120. )
  121. cloth_image: Mapped["ImageRecord"] = relationship(
  122. "ImageRecord",
  123. foreign_keys=[cloth_image_id],
  124. back_populates="cloth_processes"
  125. )
  126. result_image: Mapped[Optional["ImageRecord"]] = relationship(
  127. "ImageRecord",
  128. foreign_keys=[result_image_id],
  129. back_populates="result_processes"
  130. )
  131. __table_args__ = (
  132. Index('idx_process_user_id', 'user_id'),
  133. Index('idx_face_image_id', 'face_image_id'),
  134. Index('idx_cloth_image_id', 'cloth_image_id'),
  135. Index('idx_result_image_id', 'result_image_id'),
  136. Index('idx_completed_at', 'completed_at'),
  137. Index('idx_status', 'status'),
  138. CheckConstraint(
  139. "status IN ('已审核', '已发布', '待审核', '待发布', '已拒绝')",
  140. name="ck_process_status"
  141. ),
  142. CheckConstraint(
  143. "task_type IN ('swap_face', 'swap_cloth', 'swap_bg', 'swap_all')",
  144. name="ck_process_task_type"
  145. )
  146. )
  147. class SystemConfig(Base):
  148. """系统配置表"""
  149. __tablename__ = "system_configs"
  150. id = Column(Integer, primary_key=True, autoincrement=True, comment="配置ID")
  151. config_key = Column(String(100), nullable=False, comment="配置键")
  152. config_value = Column(Text, nullable=False, comment="配置值")
  153. config_type = Column(String(20), nullable=False, comment="配置类型(string/int/float/bool/json)")
  154. config_description = Column(Text, nullable=True, comment="配置描述")
  155. is_public = Column(Boolean, default=False, comment="是否公开配置")
  156. created_at = Column(DateTime, default=func.now(), comment="创建时间")
  157. updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
  158. __table_args__ = (
  159. Index('idx_config_key', 'config_key'),
  160. Index('idx_is_public', 'is_public'),
  161. CheckConstraint("config_type IN ('string', 'int', 'float', 'bool', 'json')", name="ck_config_type"),
  162. )
  163. class DatabaseVersion(Base):
  164. """数据库版本表"""
  165. __tablename__ = "database_versions"
  166. id = Column(Integer, primary_key=True, autoincrement=True, comment="版本ID")
  167. version = Column(String(20), unique=True, nullable=False, comment="版本号")
  168. description = Column(Text, nullable=True, comment="版本描述")
  169. applied_at = Column(DateTime, default=func.now(), comment="应用时间")
  170. migration_file = Column(String(255), nullable=True, comment="迁移文件名")
  171. __table_args__ = (
  172. Index('idx_version', 'version'),
  173. Index('idx_applied_at', 'applied_at'),
  174. )