6 个后端
1 个抽象层
PostgreSQL / MySQL / MariaDB / SQLite / Oracle / SQL Server——同一份 ActiveRecord 代码,编译期检测后端能力 + 选择合适的 dialect。能力差异是显式的(CapabilityMatrix),dialect 差异是透明的(PG 的 EXCEPT、Oracle 的 MINUS、MySQL 的 ON DUPLICATE KEY、PG 的 ON CONFLICT——你只写一份 ORM 代码)。StorageBackend ABC 还允许你实现自己的 backend。
StorageBackend · 抽象在哪里
ActiveRecord 把"怎么连数据库 / 怎么发 SQL / 怎么处理类型"全部下放给 StorageBackend ABC——上层 ActiveQuery / Builder 不知道你用的是哪种数据库,只知道它有一个 execute() 方法和一份 capabilities() 声明。这意味着:(1) 切换后端不改 ORM 代码,(2) 你可以写自己的 backend。
from rhosocial.activerecord.backend import StorageBackend
class YourBackend(StorageBackend):
def execute(self, sql, params):
return self._cursor.execute(sql, params)
def capabilities(self):
return {
"cte": True,
"recursive_cte": True,
"json": True,
"upsert": False,
}
# 注册
Model.use_backend(YourBackend("yourdb://..."))
实现 ABC 的两个方法(execute + capabilities),加上 dialect 的几个细节(quoting、placeholder、自增 ID 取回方式),就能接入任何支持 DB-API 2.0 / async DB-API 的数据库。
每一个 · 都是一等公民
每个后端有独立的子目录(backends/postgresql/、backends/mysql/ 等),里面有 setup(连接配置)、capabilities(详细能力清单)、dialect(特有语法)、ops(运维:连接池、慢查询、迁移)四类页面。点击下面的卡片进入。
能力矩阵 · 哪个后端支持哪个特性
12 项关键特性 × 6 个后端。● full 表示原生支持,◐ partial 表示有版本下限或语法限制(鼠标悬停查看具体版本),— 表示不支持。所有数据来自 主仓 README 与各 dialect 实现的 capabilities() 声明。
| 特性 | PostgreSQL | MySQL | MariaDB | SQLite | Oracle | SQL Server |
|---|---|---|---|---|---|---|
| WITH (CTE) | ● | ◐ 8.0+ | ◐ 10.2+ | ◐ 3.8.3+ | ● | ● |
| WITH RECURSIVE | ● | ◐ 8.0+ | ◐ 10.2+ | ◐ 3.8.3+ | ● | ● |
| UNION / UNION ALL | ● | ● | ● | ● | ● | ● |
| INTERSECT / EXCEPT | ● | ◐ 8.0.31+ | ◐ 10.3+ | ● | ◐ MINUS | ● |
| JSON 字段类型 | ● JSONB | ◐ JSON | ◐ JSON | ◐ JSON1 | ◐ 12c+ | ◐ 2016+ |
| ARRAY 字段类型 | ● | — | — | — | ◐ VARRAY | — |
| UPSERT (ON CONFLICT) | ● | ◐ ON DUP KEY | ◐ ON DUP KEY | ◐ 3.24+ | ◐ MERGE | ◐ MERGE |
| 窗口函数 | ● | ◐ 8.0+ | ◐ 10.2+ | ◐ 3.25+ | ● | ● |
| 分区表 | ● | ● | ● | — | ● | ● |
| RETURNING 子句 | ● | — | ◐ 10.5+ | ◐ 3.35+ | ◐ INTO | ◐ OUTPUT |
| 异步驱动 | ● | ● | ● | ● | ◐ | ◐ |
| 嵌套事务(SAVEPOINT) | ● | ● | ● | ● | ● | ● |
编译期检测:SetOperationQuery、CTEQuery、UPSERT API 等都会在编译期检查后端 capabilities()。不支持时给出明确错误("INTERSECT requires MySQL ≥ 8.0.31"),不会生成无法执行的 SQL。
选你用的后端 · 只看相关内容
能力矩阵适合横向比较。但当你已经决定用某个后端时,你只关心那一列——下面的选择器把视图收窄到单个 backend:安装命令、能力清单、版本限制、子目录链接。
同一份 ORM 代码 · 6 个 dialect 的 SQL
backend 透明的最直接证据:一份 ActiveRecord 代码 → 6 种数据库各自的方言 SQL。下面以 UPSERT(最方言敏感的 DML)为例,看 StorageBackend 怎么把同一意图翻译到 6 种语法。差异部分用高亮标出。
{"email": "alice@example.com", "name": "Alice", "login_count": 1},
conflict_on=["email"],
update_on_conflict={"login_count": User.c.login_count + 1}
)
VALUES (?, ?, 1)
ON CONFLICT (email) DO UPDATE SET
login_count = users.login_count + 1;
VALUES (?, ?, 1)
ON DUPLICATE KEY UPDATE
login_count = login_count + 1;
VALUES (?, ?, 1)
ON DUPLICATE KEY UPDATE
login_count = login_count + 1;
VALUES (?, ?, 1)
ON CONFLICT(email) DO UPDATE SET
login_count = login_count + 1;
USING (SELECT ? email, ? name FROM DUAL) src
ON (u.email = src.email)
WHEN MATCHED THEN UPDATE SET login_count = login_count + 1
WHEN NOT MATCHED THEN INSERT (...) VALUES (...);
USING (VALUES (?, ?, 1)) AS src(email, name, lc)
ON u.email = src.email
WHEN MATCHED THEN UPDATE SET login_count = login_count + 1
WHEN NOT MATCHED THEN INSERT (...) VALUES (...);
这就是 backend 抽象的价值——你不需要记住 6 种 UPSERT 语法、哪个版本支持 RETURNING、Oracle 和 MSSQL 必须用 MERGE 的细节。StorageBackend 对应的 dialect 类负责把同一意图编译到正确的 SQL。同样的差异在 INTERSECT/EXCEPT、JSON 路径、窗口函数 OVER 子句、自增主键 RETURNING 上都存在。
选哪个后端 · 三句话决定
没有"最好的后端"——只有"最适合你这个阶段、这个团队、这个部署环境的后端"。下面三个典型场景给出推荐,同一个项目可以分阶段切换(开发用 SQLite、生产用 PG),ActiveRecord 代码不变。
SQLite
无服务器,单文件
开发期间 zero-setup(pip install 即可),测试用例每次创建新内存数据库(:memory:),CI 跑得飞快。3.8.3+ 已支持 CTE,3.24+ 支持 UPSERT,3.25+ 支持窗口函数——日常 ORM 能力齐全。
PostgreSQL
能力最齐
新项目首选 PG。CTE / 递归 / JSONB / ARRAY / UPSERT / 窗口函数全部原生,索引类型最丰富(GIN / GiST / BRIN),EXPLAIN (ANALYZE, BUFFERS) 输出最详细。异步驱动 asyncpg 性能最好。
Oracle / SQL Server
团队熟悉度优先
如果公司已经有 DBA 团队、合规要求、企业许可——继续用 Oracle 或 SQL Server 没问题。StorageBackend 透明处理 MERGE / MINUS / OUTPUT 等方言差异。MariaDB 在需要 temporal 表或避开 Oracle 收购版 MySQL时是 MySQL 的合理替代。
不变的是 ActiveRecord 代码——业务逻辑、查询、模型定义不会因为切换后端而修改。这意味着从 SQLite 平滑升级到 PG / 从 MySQL 迁移到 PG 是可行路径,不需要重写应用层。当然 schema migration 仍然需要规划(不同后端的列类型、索引语法不同)——见 named-resources。
深入 backends
StorageBackend 内部
execute / fetch / capabilities 三个核心方法,dialect 类的职责,连接池如何与 backend 解耦。
6 后端深度对比
各家在性能、生态、运维难度、许可上的差异。每项对比都来自 testsuite,无营销数字。
30+ 特性矩阵
本页是 12 项核心特性。完整矩阵展开 30+ 项(partial index、generated column、check constraint 等)。
命名查询 / 命名过程
每个 backend 都可以挂自己的 named query 库(如 PG-only 的 JSON 查询)——见 named-resources。