初始版本
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
"""
|
||||
数据库模型定义
|
||||
使用 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()
|
||||
|
||||
Reference in New Issue
Block a user