中途失败就全撤
(每道题开头都有同一段:open_db() 建一个内存 SQLite 库、含 users / notes / files 三张表、交回连接;执行 SQL 用 conn.execute(SQL, 参数元组),取一行用 .fetchone()、取全部用 .fetchall()、新行主键用 .lastrowid。判题机自带 sqlite3。)
(这一节还有:batch_add(conn, uid, texts, fail_at) 一批留言要么全进要么全不进——中途出错就 rollback、成功才 commit;fail_at 指定第几条故意失败。)
一批三条:一次全成、一次插到第三条失败,各看结果和最终条数:
import sqlite3
def open_db():
"""建一个内存 SQLite 库,含 users / notes / files 三张表,交回连接。"""
conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT UNIQUE, pw TEXT)")
conn.execute("CREATE TABLE notes(id INTEGER PRIMARY KEY, uid INTEGER, text TEXT)")
conn.execute("CREATE TABLE files(id INTEGER PRIMARY KEY, uid INTEGER, name TEXT, size INTEGER)")
return conn
def add_note(conn, uid, text):
"""插一条留言,交回它的新 id(自增主键)。"""
cur = conn.execute("INSERT INTO notes(uid, text) VALUES(?, ?)", (uid, text))
return cur.lastrowid
def get_text(conn, nid):
"""按 id 取一条留言的正文;没有交回 None。"""
row = conn.execute("SELECT text FROM notes WHERE id=?", (nid,)).fetchone()
return row[0] if row else None
def update_note(conn, nid, text):
"""把某条留言的正文改掉。"""
conn.execute("UPDATE notes SET text=? WHERE id=?", (text, nid))
def delete_note(conn, nid):
"""删掉某条留言。"""
conn.execute("DELETE FROM notes WHERE id=?", (nid,))
def list_texts(conn, uid):
"""按 id 顺序交回某人所有留言正文的列表。"""
return [r[0] for r in conn.execute("SELECT text FROM notes WHERE uid=? ORDER BY id", (uid,))]
def count_notes(conn, uid):
"""数某人有几条留言。"""
return conn.execute("SELECT COUNT(*) FROM notes WHERE uid=?", (uid,)).fetchone()[0]
def batch_add(conn, uid, texts, fail_at=None):
"""一批留言要么全进、要么全不进:中途出错就 rollback,成功才 commit。交回是否成功。
fail_at 不为 None 时,插到第 fail_at 条故意抛错(模拟中途失败)。"""
try:
for i, t in enumerate(texts):
if fail_at is not None and i == fail_at:
raise ValueError("boom")
conn.execute("INSERT INTO notes(uid, text) VALUES(?, ?)", (uid, t))
conn.commit()
return True
except Exception:
conn.rollback()
return False
c1 = open_db()
ok1 = batch_add(c1, 1, ["a", "b", "c"])
c2 = open_db()
ok2 = batch_add(c2, 1, ["a", "b", "c"], fail_at=2)
print(str(ok1) + "/" + str(count_notes(c1, 1)) + "/" + str(ok2) + "/" + str(count_notes(c2, 1)))
全部评论