The most common write
INSERT looks simple but has several shapes worth knowing:
- Positional —
INSERT INTO t VALUES (...). Column order is whateverCREATE TABLEdeclared. Brittle. - Named columns —
INSERT INTO t(a, b) VALUES (...). Always use this; survives schema changes. - Multi-row —
INSERT INTO t(a) VALUES (1), (2), (3). One transaction, much faster than N single-row inserts. - INSERT ... SELECT —
INSERT INTO t(a) SELECT x FROM other. Bulk copy from another table. - RETURNING (3.35+) —
INSERT ... RETURNING id. Get back generated values without a second round-trip. - UPSERT (covered later) —
INSERT ... ON CONFLICT(...) DO UPDATE.
Tip: For a Python loop inserting thousands of rows, wrap the loop in a single transaction (
conn.execute('BEGIN') ... conn.commit()) or use executemany. Default 'one transaction per statement' is the #1 reason people think SQLite is slow.