TSts-grm

SQL 日志与追踪

调试 ORM 行为的核心手段是看生成的 SQLnewSqlClientsqlLogger 选项控制打印形态:

const client = newSqlClient(driver, {
  sqlLogger: {
    pretty: true,                    // 换行缩进美化
    parameter: "PLACEHOLDER",        // 参数呈现方式
  },
})

parameter 三种呈现

效果
PLACEHOLDER(默认)参数位显示 ?,参数值另行可见
COMMENTSQL 后追加注释(-- $1 = 79.0
INLINE参数值直接内联进 SQL 文本(调试友好,注意别在生产开)

沙盒里怎么用

沙盒每次运行都自动捕获 SQL 并显示在结果面板的 SQL 追踪区(等价于恒开日志)。演示:跑一次嵌套取形查询,看主查询与 loadAssociation 两段的真实 SQL:

// ① 模型(完整可运行版见工作区)
import { model, prop, dto } from '@ts-grm/core'
import { sqlClient } from './infra/sql-client'

const BookStore = model("BookStore", "id", class {
    id = prop.i64()
    name = prop.str(100)
})

const Book = model("Book", "id", class {
    id = prop.i64()
    name = prop.str(50)
    edition = prop.i32()
    price = prop.num(10, 2)
    store = prop.m2o(BookStore).nullable()
})

// ② 嵌套取形:SQL 追踪会显示 主查询 + loadAssociation 两段
const rows = await sqlClient.createQuery(Book, (q, book) => {
    q.orderBy(book.name)
    return q.select(book.fetch(dto.view(Book, c => [
        c.id,
        c.name,
        c.store.with(c => [c.id, c.name]),
    ])))
}).fetchList()

console.log(rows.map(r => `${r.name} @ ${r.store?.name}`).join('\n'))

阅读 SQL 追踪的要点:

  1. 看第二段的 IN 列表——批加载按主查询收集的 key 合并,恒两段;
  2. 对照预期形状——视图选了哪些列、嵌套展开成几段,都一目了然;
  3. 怀疑方言/优化问题时,把这段 SQL 复制到你的数据库 EXPLAIN。

生产建议

  • 生产一般 pretty: false + PLACEHOLDER,避免日志膨胀;
  • 连接驱动的原生日志(pg 的 pool 事件等)与 sqlLogger 是两层,按需取舍。