Prompts-MCP 686 skills · ai / design / design-pattern / framework / fundamentals / habit / lang / tech-selection /mcp/sse
lang lang/sql/ddl/tortoise-model-template.md medium

sql-tortoise-model-template

Tortoise Model 类标准模板。Use when 写 Python 后端代码 / 评审涉及 `tortoise-model-template` 的 PR。

tortoisemodelfields.intfield类标准模板
paths
  • py/models/**/*.py
  • backend/models/**/*.py

SQL · Tortoise Model 模板

标准结构

# py/models/referral.py
from tortoise import fields
from tortoise.models import Model
from models.base import TimestampMixin

class Referral(TimestampMixin, Model):
    """邀请关系(一对一:邀请人 → 被邀请人)"""

    id = fields.UUIDField(pk=True)
    inviter_session_id = fields.UUIDField(index=True)
    invitee_session_id = fields.UUIDField(unique=True)
    invite_code = fields.CharField(max_length=16, index=True)

    class Meta:
        table = "referrals"
        unique_together = (("inviter_session_id", "invitee_session_id"),)

    def __str__(self) -> str:
        return f"<Referral {self.invite_code} {self.inviter_session_id} -> {self.invitee_session_id}>"

TimestampMixin

# py/models/base.py
from tortoise import fields

class TimestampMixin:
    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

所有业务表 mixin 进来,避免重复声明。

字段类型对照表

Tortoise SQL
IntField(pk=True, generated=True) INT AUTO_INCREMENT PRIMARY KEY
UUIDField(pk=True) CHAR(36) PRIMARY KEY
CharField(max_length=N) VARCHAR(N)
TextField() TEXT
JSONField() JSON
DatetimeField(auto_now_add=True) DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6)
BooleanField(default=False) TINYINT(1) DEFAULT 0
DecimalField(max_digits=10, decimal_places=2) DECIMAL(10,2)
ForeignKeyField("models.User", related_name="orders") INT + FK

Meta 选项

class Meta:
    table = "snake_case_table_name"      # 显式表名
    unique_together = (("a", "b"),)      # 多字段唯一
    indexes = (("a", "b"),)              # 联合索引
    ordering = ["-created_at"]            # 默认排序

关系

# 1:N
class Slide(Model):
    presentation = fields.ForeignKeyField(
        "models.Presentation",
        related_name="slides",
        on_delete=fields.CASCADE,
    )

# 反向访问
p = await Presentation.get(id=pid).prefetch_related("slides")
for s in p.slides: ...

# N:M
class TextbookTag(Model):
    textbooks = fields.ManyToManyField("models.Textbook", related_name="tags")

注册到 TORTOISE_ORM

# py/main.py
TORTOISE_ORM = {
    "connections": {"default": settings.database_url},
    "apps": {
        "models": {
            "models": [
                "models.session",
                "models.textbook",
                "models.referral",
                # ...
                "aerich.models",   # 必须,Aerich 自己用
            ],
            "default_connection": "default",
        },
    },
}

自检

  • [ ] 所有 Model 继承 TimestampMixin + Model
  • [ ] Meta.table 显式声明 snake_case?
  • [ ] 索引字段加 index=True
  • [ ] 外键明确 on_delete 行为?
  • [ ] 新增 Model 后追加到 TORTOISE_ORM.models

相关