Python sqlite3.connect Function
Last modified April 15, 2025
This comprehensive guide explores Python's sqlite3.connect
function,
the primary way to interact with SQLite databases. We'll cover basic usage,
connection parameters, isolation levels, and practical examples.
Basic Definitions
The sqlite3.connect
function establishes a connection to an SQLite
database. It creates a new database file if one doesn't exist or opens an
existing one.
Key characteristics: it returns a connection object, accepts various parameters to control behavior, and manages transactions. The connection is the gateway for all database operations in SQLite.
Basic Database Connection
Here's the simplest usage of sqlite3.connect
to create or open a
database file and perform basic operations.
import sqlite3 # Connect to database (creates if doesn't exist) with sqlite3.connect('example.db') as conn: cursor = conn.cursor() # Create a table cursor.execute('''CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)''') # Insert data cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 30)) # Commit is automatic with context manager
This example shows the basic workflow using a context manager. The database file 'example.db' is created in the current directory if it doesn't exist.
The with
statement ensures the connection is properly closed and
changes are committed automatically when the block exits successfully.
Using Connection with Cursor as Context Manager
Both connection and cursor can be used as context managers for cleaner resource management.
import sqlite3 with sqlite3.connect('example.db') as conn: with conn.cursor() as cursor: cursor.execute("SELECT * FROM users") rows = cursor.fetchall() for row in rows: print(row)
This example demonstrates nested context managers for both connection and cursor. The cursor is automatically closed when its block exits.
This pattern is especially useful when working with multiple cursors or complex transaction sequences, ensuring all resources are properly released.
In-Memory Database with Context Manager
SQLite supports in-memory databases which are fast but temporary, perfect for testing.
import sqlite3 with sqlite3.connect(':memory:') as conn: with conn.cursor() as cursor: cursor.execute('''CREATE TABLE test (id INTEGER, data TEXT)''') cursor.execute("INSERT INTO test VALUES (1, 'Sample')") cursor.execute("SELECT * FROM test") print(cursor.fetchone()) # (1, 'Sample')
The special :memory:
filename creates a database in RAM. It's much
faster than disk-based databases but disappears when the connection closes.
The context manager ensures the in-memory database is properly cleaned up even if an error occurs during operations.
Connection with Isolation Level
The isolation_level parameter controls SQLite's transaction behavior. This example shows how to use different isolation levels with context managers.
import sqlite3 # Connect with explicit isolation level with sqlite3.connect('transactions.db', isolation_level='IMMEDIATE') as conn: with conn.cursor() as cursor: cursor.execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1") cursor.execute("UPDATE accounts SET balance = balance + 100 WHERE id = 2")
This example uses IMMEDIATE
isolation level which locks the database
immediately on write. The context manager handles commit/rollback automatically.
If any error occurs during the transaction, the context manager will automatically roll back the changes before closing the connection.
Custom Row Factory with Context Manager
The row_factory
parameter allows customizing how rows are returned,
enabling access by column name.
import sqlite3 with sqlite3.connect('example.db') as conn: conn.row_factory = sqlite3.Row # Built-in row factory with conn.cursor() as cursor: cursor.execute("SELECT * FROM users LIMIT 1") row = cursor.fetchone() print(row['name']) # Access by column name
This example uses SQLite's built-in Row
factory that provides named
access to columns. The context managers ensure proper cleanup of resources.
Named access improves code readability and maintainability, especially with queries returning many columns or when schema might change.
Connection with Timeout
The timeout
parameter specifies how long to wait when a database is
locked by another connection.
import sqlite3 try: # Connect with 5 second timeout with sqlite3.connect('busy.db', timeout=5.0) as conn: with conn.cursor() as cursor: cursor.execute("UPDATE counters SET value = value + 1 WHERE id = 1") except sqlite3.OperationalError as e: print("Database locked beyond timeout:", e)
This connection will wait up to 5 seconds if the database is locked by another process. The context manager handles the connection lifecycle.
The timeout is particularly important in multi-process applications where database contention might occur. The try/except handles timeout errors.
URI Connection with Context Manager
The uri
parameter enables advanced connection options through URI
format connection strings.
import sqlite3 # Connect with URI parameters uri = 'file:app.db?mode=rwc&cache=shared' with sqlite3.connect(uri, uri=True, timeout=10) as conn: with conn.cursor() as cursor: cursor.execute("PRAGMA journal_mode=WAL") cursor.execute("SELECT * FROM config") print(cursor.fetchall())
This example shows a URI connection with mode, cache, and timeout parameters. The context managers ensure proper resource cleanup.
URI connections support many configuration options not available through regular connection strings, providing more control over database behavior.
Best Practices
- Always use context managers: For automatic resource cleanup
- Choose appropriate isolation: Match isolation level to use case
- Handle errors properly: Catch specific SQLite exceptions
- Use parameterized queries: Prevent SQL injection
- Consider connection pooling: For high-performance apps
Source References
Author
List all Python tutorials.