Prompts-MCP 686 skills · ai / design / design-pattern / framework / fundamentals / habit / lang / tech-selection /mcp/sse
lang lang/sql/select/explicit-column-list.md medium

sql-explicit-column-list

SELECT 必须显式列出列名 — 禁 SELECT *。Use when 写 Python 后端代码 / 评审涉及 `explicit-column-list` 的 PR。

selectqueryraw_queryfetch必须显式须显式列显式列出
paths
  • py/**/*.py
  • backend/**/*.py
  • **/*.sql

SQL · SELECT 显式列出列名

规则

任何生产 SQL(含 ORM raw、Alembic data migration、seed 脚本)必须显式列出查询的列,禁 SELECT *

反例 → 正例

# ❌
rows = await conn.execute_query_dict("SELECT * FROM presentations WHERE owner_id = %s", [uid])

# ✅
rows = await conn.execute_query_dict(
    "SELECT id, title, theme_id, created_at FROM presentations WHERE owner_id = %s",
    [uid],
)

Tortoise ORM 等价

# ❌ 默认查全列
items = await Presentation.filter(owner_id=uid)

# ✅ 性能敏感场景用 only / values
items = await Presentation.filter(owner_id=uid).only("id", "title", "theme_id", "created_at")

# ✅ 只要 dict 不要 ORM 对象
data = await Presentation.filter(owner_id=uid).values("id", "title", "theme_id")

为什么

  1. Schema 变更(加列)后行为静默改变
  2. ORM 反序列化遇到未声明列抛 / 忽略(Tortoise 抛 FieldError
  3. 索引覆盖优化失效——强迫回表
  4. 网络/磁盘 IO 浪费

CI 检测

grep -RIn "SELECT \*\|select \*" --include="*.py" --include="*.sql" backend/ py/

命中即 fail。

例外(仅一种)

DBA 交互式排查(DBeaver / mysql CLI)的临时查询。不得提交到仓库

自检

  • [ ] 仓库内无 SELECT *
  • [ ] Tortoise 性能敏感场景用 .only() / .values()
  • [ ] 列变更前确认所有引用方?

相关