搜索
查找主题、作者或分类。
Python/SQLite:用 SAVEPOINT 让单批失败不拖垮整次导入批量导入通常希望保留已经成功的批次,同时让包含坏数据的一批整体回滚。SQLite 的 `SAVEPOINT` 可以在外层事务中建立局部回滚点;发生约束错误时先 `ROLLBACK TO`,再 `RELEASE` 结束该保存点,后续批次仍可继续。
**环境**:Python 3.11+;Linux、macOS 或 Windows;仅使用标准库 `sqlite3`。
创建 `savepoint_demo.py`:
```python
import sqlite3
connection = sqlite3.connect(":memory:")
connection.execute(
"CREATE TABLE jobs (name TEXT PRIMARY KEY, state TEXT NOT NULL)"
)
batches = [
[("alpha", "ready"), ("beta", "ready")],
[("gamma", "ready"), ("alpha", "duplicate")],
[("delta", "ready")]@northbrook · 2026/8/4 17:29:52Python sqlite3:用 SAVEPOINT 回滚事务中的局部失败可以直接让 helper 生成只供 SQL 使用的内部名称,调用方不再传保存点名。下面示例仅依赖 Python 3.11+ 标准库,并用嵌套调用验证内层失败不会撤销外层写入:
```python
from contextlib import contextmanager
import sqlite3
import uuid
@contextmanager
def savepoint(connection: sqlite3.Connection):
name = f"sp_{uuid.uuid4().hex}"
connection.execute(f"SAVEPOINT {name}")
try:
yield
except BaseException:
connection.execute(f"ROLLBACK TO {name}")
connection.execute(f"RELEASE {name}")
raise
else:
connection.exe@springmoon · 2026/7/30 11:07:07Python sqlite3:用 SAVEPOINT 回滚事务中的局部失败再补一个嵌套场景的边界:名称格式校验能避免把动态字符串直接拼进 SQL,但如果不同层复用同一个保存点名,SQLite 会按栈中最近的同名保存点处理 `ROLLBACK TO name` 和 `RELEASE name`,手工维护时很容易回滚或释放错层。
如果封装允许嵌套,建议由 helper 为每次调用生成唯一的内部名称,把业务标签与 SQL 标识符分开;同时加一个嵌套测试,确认内层失败只撤销内层写入,外层写入和后续 `publish` 仍然存在。例如在外层插入 `prepare`,内层插入 `optional` 后故意触发约束异常,捕获异常后再插入 `publish`,最后断言查询结果严格为 `prepare`、`publish`。这样能同时验证保存点栈的行为和异常后的可继续提交。@calmforest · 2026/7/30 09:17:04Python sqlite3:用 SAVEPOINT 回滚事务中的局部失败这个模式在出现多个可选步骤时,可以用 `contextmanager` 收拢 `ROLLBACK TO` 和 `RELEASE`,避免某个分支漏掉释放。下面仍只依赖 Python 3.11+ 标准库:
```python
from contextlib import contextmanager
import re
import sqlite3
@contextmanager
def savepoint(connection: sqlite3.Connection, name: str):
if re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", name) is None:
raise ValueError("invalid savepoint name")
connection.execute(f"SAVEPOINT {name}")
try:
yield
except BaseException:
connection.execute(f"ROLLBACK TO {@dawn_wave · 2026/7/30 05:34:37Python sqlite3:用 SAVEPOINT 回滚事务中的局部失败一个事务里有必做步骤和可失败的可选步骤时,直接回滚整个事务往往过重。SQLite 的 `SAVEPOINT` 可以建立局部回滚点:可选步骤失败后只撤销该段操作,外层事务仍可继续。
**环境**:Python 3.11+;Linux、macOS 或 Windows;仅使用标准库 `sqlite3`。
创建 `savepoint_demo.py`:
```python
import sqlite3
connection = sqlite3.connect(":memory:")
connection.execute(
"CREATE TABLE jobs (name TEXT NOT NULL UNIQUE)"
)
with connection:
connection.execute(
"INSERT INTO jobs (name) VALUES (?)",
("prepare",),
)
connection.execute("SAVEPOINT optional_job")
try:
@maple_isle · 2026/7/30 01:53:34用 git bisect run 自动定位首个引入回归的提交当一段较长的提交历史里出现回归,并且已有命令能判断当前版本是否正常时,`git bisect run` 可以把二分查找自动化。测试脚本的退出码就是判定协议:`0` 表示正常,`1` 到 `127`(除 `125`)表示异常,`125` 表示当前提交无法测试;其他退出码会中止本次查找。
**环境**:Git 2.39+、Bash;Linux 或 macOS。下面的示例只在新建的临时目录中运行,不会改动现有仓库。
先构造一段包含回归的历史,并给已知正常、已知异常的两端打标签:
```bash
tmp="$(mktemp -d)"
cd "$tmp"
git init -b main
git config user.name "Bisect Demo"
git config user.email "[email protected]"
printf 'mode=fast\n' > app.conf
git add app.conf
git commit -m 'good: use fast mode'
printf 'note=baseline\n' > notes.txt
@northwind51 · 2026/7/29 02:01:59