Last modified: Sep 22, 2026
Querying SQLite in Python: A Beginner's Guide
SQLite is a lightweight, file-based database engine that works perfectly with Python. It requires no separate server setup. This makes it ideal for small to medium applications.
In this guide, we'll explore how to query SQLite databases in Python. We'll cover connecting to databases, executing queries, and retrieving results.
Getting Started with SQLite in Python
Python includes the built-in sqlite3 module. No additional installation is required for basic usage.
Let's start by creating a simple database connection:
import sqlite3
# Connect to SQLite database (or create it)
conn = sqlite3.connect('example.db')
# Create a cursor object
cursor = conn.cursor()
print("Connection established successfully")
Connection established successfully
The connect() function creates a connection to the database file. If the file doesn't exist, SQLite creates it automatically.
Creating Tables and Inserting Data
Before querying data, we need a table with some records. Here's how to create a table and insert sample data:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Create table
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
age INTEGER,
city TEXT
)
''')
# Insert sample data
users_data = [
(1, 'Alice', 25, 'New York'),
(2, 'Bob', 30, 'Los Angeles'),
(3, 'Charlie', 35, 'Chicago'),
(4, 'Diana', 28, 'Houston')
]
cursor.executemany('INSERT INTO users VALUES (?, ?, ?, ?)', users_data)
# Commit changes
conn.commit()
print("Table created and data inserted successfully")
Table created and data inserted successfully
Executing Basic SELECT Queries
The most common operation is retrieving data using SELECT statements. Let's fetch all records from our users table:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Execute SELECT query
cursor.execute('SELECT * FROM users')
# Fetch all results
results = cursor.fetchall()
# Display results
for row in results:
print(row)
(1, 'Alice', 25, 'New York')
(2, 'Bob', 30, 'Los Angeles')
(3, 'Charlie', 35, 'Chicago')
(4, 'Diana', 28, 'Houston')
The fetchall() method retrieves all matching rows. Each row comes back as a tuple.
Filtering Results with WHERE Clause
Often you need specific records. Use WHERE clauses to filter data:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Query with WHERE clause
cursor.execute('SELECT name, age FROM users WHERE age > 28')
results = cursor.fetchall()
for row in results:
print(f"Name: {row[0]}, Age: {row[1]}")
Name: Bob, Age: 30
Name: Charlie, Age: 35
Name: Diana, Age: 28
Using Parameterized Queries
Never concatenate user input directly into SQL strings. This creates SQL injection vulnerabilities.
Use parameterized queries instead:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Safe parameterized query
min_age = 30
cursor.execute('SELECT * FROM users WHERE age >= ?', (min_age,))
results = cursor.fetchall()
for row in results:
print(row)
(2, 'Bob', 30, 'Los Angeles')
(3, 'Charlie', 35, 'Chicago')
Question marks (?) act as placeholders. The actual values are passed as a tuple in the second parameter.
Retrieving Single Rows
When you expect only one result, use the fetchone() method:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Find user by ID
user_id = 2
cursor.execute('SELECT name, city FROM users WHERE id = ?', (user_id,))
result = cursor.fetchone()
if result:
print(f"User found: {result[0]} from {result[1]}")
else:
print("User not found")
User found: Bob from Los Angeles
For more details on retrieving single rows, check our comprehensive fetchone guide.
Sorting Results with ORDER BY
You can sort query results using ORDER BY:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Sort by age in descending order
cursor.execute('SELECT name, age FROM users ORDER BY age DESC')
results = cursor.fetchall()
for row in results:
print(f"{row[0]}: {row[1]} years old")
Charlie: 35 years old
Bob: 30 years old
Diana: 28 years old
Alice: 25 years old
Aggregation Functions
SQLite supports aggregation functions like COUNT, AVG, and SUM:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Count total users
cursor.execute('SELECT COUNT(*) FROM users')
total_users = cursor.fetchone()[0]
print(f"Total users: {total_users}")
# Calculate average age
cursor.execute('SELECT AVG(age) FROM users')
avg_age = cursor.fetchone()[0]
print(f"Average age: {avg_age:.1f}")
# Sum of ages (just for demonstration)
cursor.execute('SELECT SUM(age) FROM users')
total_age = cursor.fetchone()[0]
print(f"Sum of ages: {total_age}")
Total users: 4
Average age: 29.5
Sum of ages: 118
Joining Tables
Real-world databases often contain multiple related tables. Here's how to join them:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Create orders table
cursor.execute('''
CREATE TABLE IF NOT EXISTS orders (
order_id INTEGER PRIMARY KEY,
user_id INTEGER,
product TEXT,
amount REAL,
FOREIGN KEY (user_id) REFERENCES users(id)
)
''')
# Insert order data
orders_data = [
(101, 1, 'Laptop', 999.99),
(102, 1, 'Mouse', 25.50),
(103, 2, 'Keyboard', 75.00),
(104, 3, 'Monitor', 299.99)
]
cursor.executemany('INSERT INTO orders VALUES (?, ?, ?, ?)', orders_data)
conn.commit()
# Join users and orders
cursor.execute('''
SELECT u.name, o.product, o.amount
FROM users u
JOIN orders o ON u.id = o.user_id
ORDER BY u.name
''')
results = cursor.fetchall()
for row in results:
print(f"{row[0]} ordered {row[1]} for ${row[2]}")
Alice ordered Laptop for $999.99
Alice ordered Mouse for $25.5
Bob ordered Keyboard for $75.0
Charlie ordered Monitor for $299.99
Updating Records
To modify existing data, use UPDATE statements:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Update user's age
new_age = 26
user_name = 'Alice'
cursor.execute('UPDATE users SET age = ? WHERE name = ?', (new_age, user_name))
# Verify update
cursor.execute('SELECT name, age FROM users WHERE name = ?', (user_name,))
result = cursor.fetchone()
print(f"Updated record: {result}")
conn.commit()
Updated record: ('Alice', 26)
Deleting Records
Remove records carefully using DELETE statements:
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Delete specific user
user_id_to_delete = 4
cursor.execute('DELETE FROM users WHERE id = ?', (user_id_to_delete,))
# Verify deletion
cursor.execute('SELECT COUNT(*) FROM users')
remaining_count = cursor.fetchone()[0]
print(f"Remaining users: {remaining_count}")
conn.commit()
Remaining users: 3
Proper Resource Management
Always close your database connections. Use context managers for automatic cleanup:
import sqlite3
# Using context manager for automatic cleanup
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
cursor.execute('SELECT * FROM users')
results = cursor.fetchall()
for row in results:
print(row)
# Connection automatically closed after 'with' block
print("Connection closed automatically")
(1, 'Alice', 26, 'New York')
(2, 'Bob', 30, 'Los Angeles')
(3, 'Charlie', 35, 'Chicago')
Connection closed automatically
Conclusion
Querying SQLite databases in Python is straightforward once you understand the core concepts. Key takeaways include:
- Use the built-in
sqlite3module - Always use parameterized queries to prevent SQL injection
- Close connections properly using context managers
- Leverage aggregation functions for data analysis
- Use JOINs to work with related data across tables
For Flask web applications, SQLite integrates seamlessly. Learn more in our Flask SQLite integration guide.
Practice these techniques with different datasets. Soon, querying SQLite in Python will become second nature.