145 lines
4.9 KiB
Python
145 lines
4.9 KiB
Python
"""
|
|
数据库模型定义
|
|
使用 SQLModel 定义所有表结构
|
|
"""
|
|
from datetime import datetime, date
|
|
from typing import Optional
|
|
from sqlmodel import SQLModel, Field, Relationship, Column
|
|
from sqlalchemy import Numeric
|
|
from decimal import Decimal
|
|
|
|
|
|
# ==================== 用户表 ====================
|
|
class User(SQLModel, table=True):
|
|
"""用户表"""
|
|
__tablename__ = "users"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
username: str = Field(max_length=50, unique=True, index=True)
|
|
email: Optional[str] = Field(default=None, max_length=100, unique=True, index=True)
|
|
hashed_password: str
|
|
created_at: datetime = Field(default_factory=datetime.now)
|
|
|
|
|
|
# ==================== 待办事项表 ====================
|
|
class Todo(SQLModel, table=True):
|
|
"""待办事项表"""
|
|
__tablename__ = "todos"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
title: str = Field(max_length=200)
|
|
done: bool = Field(default=False)
|
|
created_at: datetime = Field(default_factory=datetime.now)
|
|
user_id: int = Field(foreign_key="users.id", index=True)
|
|
|
|
# 关系(可选,用于ORM查询)
|
|
user: Optional[User] = Relationship()
|
|
|
|
|
|
# ==================== 博客文章表 ====================
|
|
class Post(SQLModel, table=True):
|
|
"""博客文章表"""
|
|
__tablename__ = "posts"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
title: str = Field(max_length=200)
|
|
slug: str = Field(max_length=200, index=True)
|
|
content: str # 支持 Markdown
|
|
created_at: datetime = Field(default_factory=datetime.now)
|
|
updated_at: Optional[datetime] = Field(default=None)
|
|
user_id: int = Field(foreign_key="users.id", index=True)
|
|
|
|
# 关系
|
|
user: Optional[User] = Relationship()
|
|
|
|
|
|
# ==================== 记账记录表 ====================
|
|
class Transaction(SQLModel, table=True):
|
|
"""记账记录表"""
|
|
__tablename__ = "transactions"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
amount: Decimal = Field(sa_column=Column(Numeric(10, 2))) # 正数为收入,负数为支出
|
|
category: str = Field(max_length=50)
|
|
description: Optional[str] = Field(default=None, max_length=200)
|
|
date: date
|
|
user_id: int = Field(foreign_key="users.id", index=True)
|
|
|
|
# 关系
|
|
user: Optional[User] = Relationship()
|
|
|
|
|
|
# ==================== 媒体-标签关联表(多对多)====================
|
|
class MediaTag(SQLModel, table=True):
|
|
"""媒体-标签关联表"""
|
|
__tablename__ = "media_tags"
|
|
|
|
media_id: int = Field(foreign_key="media.id", primary_key=True)
|
|
tag_id: int = Field(foreign_key="tags.id", primary_key=True)
|
|
|
|
|
|
# ==================== 书影音收藏表 ====================
|
|
class Media(SQLModel, table=True):
|
|
"""书影音收藏表"""
|
|
__tablename__ = "media"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
title: str = Field(max_length=200)
|
|
media_type: str = Field(max_length=20) # book / movie / music
|
|
rating: Optional[float] = Field(default=None, ge=0.0, le=5.0)
|
|
comment: Optional[str] = Field(default=None)
|
|
external_id: Optional[str] = Field(default=None, max_length=100) # ISBN、IMDb ID等
|
|
cover_url: Optional[str] = Field(default=None, max_length=300)
|
|
created_at: datetime = Field(default_factory=datetime.now)
|
|
user_id: int = Field(foreign_key="users.id", index=True)
|
|
|
|
# 关系
|
|
user: Optional[User] = Relationship()
|
|
tags: list["Tag"] = Relationship(back_populates="media", link_model=MediaTag)
|
|
|
|
|
|
# ==================== 媒体标签表 ====================
|
|
class Tag(SQLModel, table=True):
|
|
"""媒体标签表"""
|
|
__tablename__ = "tags"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
name: str = Field(max_length=50, unique=True, index=True)
|
|
|
|
# 关系
|
|
media: list[Media] = Relationship(back_populates="tags", link_model=MediaTag)
|
|
|
|
|
|
# ==================== 聊天消息表 ====================
|
|
class ChatMessage(SQLModel, table=True):
|
|
"""聊天消息表"""
|
|
__tablename__ = "chat_messages"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
content: str
|
|
sent_at: datetime = Field(default_factory=datetime.now)
|
|
user_id: int = Field(foreign_key="users.id", index=True)
|
|
room: str = Field(max_length=50, default="main", index=True)
|
|
|
|
# 关系
|
|
user: Optional[User] = Relationship()
|
|
|
|
|
|
# ==================== 文件上传记录表 ====================
|
|
class Upload(SQLModel, table=True):
|
|
"""文件上传记录表"""
|
|
__tablename__ = "uploads"
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
filename: str = Field(max_length=200)
|
|
stored_path: str = Field(max_length=300)
|
|
file_size: int # 字节数
|
|
mime_type: str = Field(max_length=100)
|
|
uploaded_at: datetime = Field(default_factory=datetime.now)
|
|
expires_at: Optional[datetime] = Field(default=None)
|
|
user_id: int = Field(foreign_key="users.id", index=True)
|
|
|
|
# 关系
|
|
user: Optional[User] = Relationship()
|
|
|