SQLite with Python
Use SQLite in Python with the built-in sqlite3 module. No dependencies required.
Python ships with SQLite support built in. The sqlite3 module is part of the standard library, so there's nothing to install.
Quick start
Three lines to get a working database:
Connecting to a database
sqlite3.connect() opens an existing database file or creates one if it doesn't exist:
To work with a temporary in-memory database, pass ":memory:" instead of a file path:
In-memory databases are fast and isolated. They disappear when the connection closes, which makes them useful for tests.
Creating tables
Use cursor.execute() to run DDL statements, then call conn.commit() to persist the change:
CREATE TABLE IF NOT EXISTS prevents an error if the table already exists. Always commit after DDL and DML statements when not using a context manager.
Inserting rows
Insert a single row by passing a tuple of values as the second argument to execute():
To insert multiple rows at once, use executemany() with a list of tuples:
executemany() is more efficient than calling execute() in a loop because it batches the operations in a single transaction.
Parameterized queries
The ? placeholders in the examples above are parameterized queries. Always use them when incorporating user input or external data into a query.
String formatting a query like this is dangerous:
A user could enter '; DROP TABLE products; -- and destroy your data. With parameterized queries, the value is treated as data, not SQL:
Note the trailing comma inside the tuple. Python requires it to distinguish a single-element tuple from a parenthesized expression.
Querying data
After executing a SELECT, fetch results with fetchone(), fetchall(), or fetchmany():
You can also iterate over a cursor directly, which avoids loading all rows into memory at once:
Using context managers
The with statement handles commits and rollbacks automatically. If the block completes without error, the connection commits. If an exception is raised, it rolls back:
Note that the context manager does not close the connection. Call conn.close() explicitly when you're done, or use a nested with block for fully automatic cleanup.
Row factories: dict-like access
By default, rows are plain tuples. Assign sqlite3.Row as the row factory to get named column access:
sqlite3.Row supports both index access (row[0]) and name access (row["name"]), and it works with dict(row) to convert to a plain dictionary.
Transactions
SQLite wraps statements in transactions automatically, but the exact behavior depends on how you use the connection.
By default, sqlite3 operates in deferred transaction mode. DML statements (INSERT, UPDATE, DELETE) are held until you call conn.commit(). To discard pending changes, call conn.rollback():
To disable implicit transaction management and run in autocommit mode, set isolation_level to None:
In autocommit mode, each statement commits immediately. Use this carefully, as there is no rollback.
Error handling
The sqlite3 module raises specific exceptions for different failure conditions:
Common exceptions:
sqlite3.IntegrityError: constraint violations (NOT NULL, UNIQUE, foreign key)sqlite3.OperationalError: table doesn't exist, locked database, syntax errorssqlite3.ProgrammingError: misuse of the API (wrong number of parameters, closed cursor)
All of these are subclasses of sqlite3.DatabaseError, which is itself a subclass of the base sqlite3.Error.
Working with pandas
If you have pandas installed, you can move data between DataFrames and SQLite with two functions.
Read a query result into a DataFrame:
Write a DataFrame back to a table:
if_exists accepts "fail" (default), "replace", or "append".
In-memory databases for testing
In-memory databases are a clean way to test database logic without touching the filesystem:
Each test gets a fresh, isolated database with no cleanup required between runs.
Common pitfalls
Forgetting to commit. Changes made with execute() are not saved until you call conn.commit(). If you close the connection without committing, the changes are lost. Use context managers to avoid this.
Thread safety. By default, a sqlite3 connection can only be used from the thread that created it. If you need to share a database across threads, either create separate connections per thread or pass check_same_thread=False when connecting and manage your own locking.
Not closing connections. Open connections hold file locks. In long-running applications, close connections explicitly or use context managers to release them when done.