The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Open an in-memory databasecon = sqlite3.connect(':memory:')View examples
Open a database filecon = sqlite3.connect('app.db', timeout=5.0)View examples
Create a table safelycon.execute('CREATE TABLE IF NOT EXISTS task(id INTEGER PRIMARY KEY, title TEXT NOT NULL)')View examples
Bind positional valuescon.execute('SELECT * FROM task WHERE id = ?', (task_id,))View examples
Bind named valuescon.execute('UPDATE task SET done = :done WHERE id = :id', {'done': 1, 'id': task_id})View examples
Insert a batchcon.executemany('INSERT INTO task(title) VALUES(?)', [(title,) for title in titles])View examples
Commit or roll back a unitwith con: con.execute('UPDATE account SET balance = balance - ? WHERE id = ?', (amount, account_id))View examples
Select PEP 249 controlcon = sqlite3.connect('app.db', autocommit=False)View examples
Inspect transaction stateif con.in_transaction: con.rollback()View examples
Enforce foreign keyscon.execute('PRAGMA foreign_keys = ON')View examples
Handle constraint failuresexcept sqlite3.IntegrityError as error: con.rollback()View examples
Read columns by namecon.row_factory = sqlite3.RowView examples
Fetch one resultrow = con.execute('SELECT title FROM task WHERE id = ?', (task_id,)).fetchone()View examples
Create a nested recovery pointcon.execute('SAVEPOINT before_optional_work')View examples
Undo to a savepointcon.execute('ROLLBACK TO SAVEPOINT before_optional_work')View examples
Copy a live databasesource.backup(destination, pages=100)View examples

Python's sqlite3 module provides an embedded transactional database through the standard DB-API interface. Treat the database as a durable boundary: bind every value, define constraints in the schema, make transaction ownership explicit, close connections deliberately, and test failure paths as carefully as successful queries.

Step by step

Detailed examples

01

Own the connection and encode invariants in the schema

A Connection represents one database session and should be closed explicitly; since Python 3.13, abandoning an unclosed connection can emit ResourceWarning. Use :memory: for isolated tests and a path for persistence. Declare PRIMARY KEY, NOT NULL, UNIQUE, CHECK, and foreign-key rules in SQL so every writer—not only one Python call site—shares the same guarantees.

Create and summarize a constrained table
import sqlite3

con = sqlite3.connect(':memory:')
try:
    con.execute('CREATE TABLE score(name TEXT PRIMARY KEY, points INTEGER NOT NULL CHECK(points >= 0))')
    con.executemany('INSERT INTO score VALUES(?, ?)', [('Ada', 3), ('Lin', 5)])
    con.commit()
    print(con.execute('SELECT COUNT(*), SUM(points) FROM score').fetchone())
finally:
    con.close()
Output
(2, 8)
Back to quick reference ↑
02

Bind values; allow-list identifiers

Never interpolate values into SQL with f-strings, percent formatting, or concatenation. Pass a sequence for ? placeholders or a dictionary for :name placeholders; the driver quotes and adapts each value safely. Placeholders represent values only, not table names, column names, directions, or SQL keywords. Choose those structural fragments from an application-owned allow-list before composing SQL.

Store hostile-looking text as ordinary data
import sqlite3

con = sqlite3.connect(':memory:')
con.execute('CREATE TABLE note(body TEXT NOT NULL)')
supplied = "'); DROP TABLE note; --"
con.execute('INSERT INTO note(body) VALUES(?)', (supplied,))
con.executemany('INSERT INTO note(body) VALUES(:body)', [{'body': 'safe'}, {'body': 'also safe'}])
rows = con.execute('SELECT body FROM note ORDER BY rowid').fetchall()
print(len(rows))
print(rows[0][0])
con.close()
Output
3
'); DROP TABLE note; --
Back to quick reference ↑
03

Make transaction boundaries visible

Connection as a context manager commits a pending transaction when its block succeeds and rolls back when the block raises, but it neither opens nor closes the connection by itself. Python 3.12 added the autocommit parameter; autocommit=False provides recommended PEP 249 behavior, while LEGACY_TRANSACTION_CONTROL is still the default in Python 3.14 and is documented to change in a future release. Set the mode deliberately instead of relying on that moving default.

Roll back an entire failed transfer
import sqlite3

con = sqlite3.connect(':memory:')
con.execute('CREATE TABLE account(name TEXT PRIMARY KEY, balance INTEGER NOT NULL)')
con.executemany('INSERT INTO account VALUES(?, ?)', [('checking', 100), ('savings', 50)])
con.commit()
try:
    with con:
        con.execute('UPDATE account SET balance = balance - 30 WHERE name = ?', ('checking',))
        raise RuntimeError('credit service unavailable')
except RuntimeError:
    pass
print(con.execute('SELECT name, balance FROM account ORDER BY name').fetchall())
con.close()
Output
[('checking', 100), ('savings', 50)]
Back to quick reference ↑
04

Let SQLite reject invalid state

Constraint violations raise sqlite3.IntegrityError, a narrower exception than DatabaseError. SQLite foreign-key enforcement must be enabled separately for each connection, normally immediately after connecting and before a transaction begins. Catch an integrity failure only where the application can translate or recover from that expected conflict; do not turn programming, disk, or locking failures into misleading validation messages.

Enforce parent-child integrity
import sqlite3

con = sqlite3.connect(':memory:')
con.execute('PRAGMA foreign_keys = ON')
con.execute('CREATE TABLE project(id INTEGER PRIMARY KEY)')
con.execute('CREATE TABLE task(project_id INTEGER NOT NULL REFERENCES project(id))')
con.execute('INSERT INTO project VALUES(1)')
try:
    con.execute('INSERT INTO task VALUES(?)', (99,))
except sqlite3.IntegrityError as error:
    print(type(error).__name__)
print(con.execute('SELECT COUNT(*) FROM task').fetchone()[0])
con.close()
Output
IntegrityError
0
Back to quick reference ↑
05

Choose a row shape and deterministic ordering

Rows are tuples by default. Assign sqlite3.Row to Connection.row_factory before creating cursors to support both numeric and case-insensitive named lookup with low overhead. Select only required columns, handle fetchone returning None, and include ORDER BY whenever order matters—SQL does not promise insertion order without it.

Read named fields from ordered results
import sqlite3

con = sqlite3.connect(':memory:')
con.row_factory = sqlite3.Row
con.execute('CREATE TABLE item(id INTEGER PRIMARY KEY, label TEXT NOT NULL)')
con.executemany('INSERT INTO item(label) VALUES(?)', [('gamma',), ('alpha',), ('beta',)])
rows = con.execute('SELECT id, label FROM item ORDER BY label').fetchall()
print([row['label'] for row in rows])
print(rows[0].keys())
con.close()
Output
['alpha', 'beta', 'gamma']
['id', 'label']
Back to quick reference ↑
06

Use savepoints for partial recovery and backup for durability

BEGIN transactions do not nest in SQLite. SAVEPOINT, ROLLBACK TO, and RELEASE provide nested recovery points inside a larger transaction; ROLLBACK TO keeps the savepoint active until RELEASE. Connection.backup copies a consistent snapshot and can operate while the source is in use. A backup is not verified disaster recovery: store copies separately and regularly test that they open and contain the expected data.

Undo optional work and copy the final state
import sqlite3

source = sqlite3.connect(':memory:')
source.execute('CREATE TABLE event(name TEXT NOT NULL)')
source.execute("INSERT INTO event VALUES('kept')")
source.execute('SAVEPOINT optional')
source.execute("INSERT INTO event VALUES('discarded')")
source.execute('ROLLBACK TO optional')
source.execute('RELEASE optional')
source.commit()
copy = sqlite3.connect(':memory:')
source.backup(copy)
print(copy.execute('SELECT name FROM event').fetchall())
source.close()
copy.close()
Output
[('kept',)]
Back to quick reference ↑

Local code tester

Query a safe in-memory database

Edit the parameterized inserts and query while keeping values separate from SQL syntax.

Runs in your browser
Output
Press Run to load Python locally.

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Python Software Foundationsqlite3 — DB-API 2.0 interface for SQLite databasesdocs.python.org
  2. SQLite ProjectTransactionsqlite.org
  3. SQLite ProjectSQLite Foreign Key Supportsqlite.org
  4. SQLite ProjectSQLite Is Transactionalsqlite.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback