Connecting from Application Code

Every example so far in this track has been run through the sqlite3 command-line shell. In a real app, though, RecipeBox's SQL runs from inside actual application code — a Python script, a PHP backend, a Node service, or an Android app. This lesson shows short, correct snippets for connecting and querying from several of the most common environments, all using parameterized queries as covered in the previous lesson.

Python — the Built-In sqlite3 Module

Python ships SQLite support in its standard library — no install required. Connecting opens (or creates) the database file directly.

# connect.py
import sqlite3

conn = sqlite3.connect('recipebox.db')
cursor = conn.cursor()

# Parameterized query: the ? is bound safely, never string-concatenated
cursor.execute(
    "SELECT id, title FROM recipes WHERE user_id = ?",
    (user_id,)
)
for row in cursor.fetchall():
    print(row)

conn.close()
Note: Python's sqlite3 module uses ? placeholders (or named placeholders like :user_id) — never Python's own string formatting (f"...", %, .format()) to build a query with user input.

PHP — PDO

This site is built on PHP, and PHP's PDO (PHP Data Objects) extension talks to SQLite the same way it talks to MySQL or PostgreSQL — one consistent API across drivers, just with a different connection string.

// connect.php
$pdo = new PDO('sqlite:recipebox.db');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// Parameterized query using a named placeholder
$stmt = $pdo->prepare('SELECT id, title FROM recipes WHERE user_id = :user_id');
$stmt->execute(['user_id' => $userId]);

foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $recipe) {
    echo $recipe['title'] . "\n";
}

$pdo->prepare() plus execute() with bound values is exactly the parameterized-query pattern from the previous lesson — PDO handles the escaping, so $userId is never pasted directly into the SQL string.

Node.js — better-sqlite3

better-sqlite3 is a popular Node package for talking to SQLite — synchronous and fast, which fits SQLite's local, embedded nature well (there's no network round-trip to wait on asynchronously).

// connect.js
const Database = require('better-sqlite3');
const db = new Database('recipebox.db');

// Parameterized query using a ? placeholder
const recipes = db.prepare('SELECT id, title FROM recipes WHERE user_id = ?').all(userId);

for (const recipe of recipes) {
  console.log(recipe.title);
}

Android / Java — SQLiteOpenHelper and Room

SQLite is built directly into Android — every Android device already has the engine on board. There are two common ways to use it from app code:

  • SQLiteOpenHelper — Android's lower-level, direct API. You write raw SQL yourself and manage the connection lifecycle by hand.
  • Room — the modern, recommended persistence library built on top of SQLite. You define entities and DAOs with annotations, and Room generates the SQL (including parameterized queries) for you at compile time.
// A Room DAO method — Room generates the parameterized SQL underneath
@Query("SELECT * FROM recipes WHERE user_id = :userId")
List<Recipe> getRecipesForUser(int userId);
Where this fits: This site's Android Java, Kotlin, and Jetpack Compose tracks cover Room in depth — entities, DAOs, and the RecipeBox database itself. Whatever Room generates behind the scenes is exactly the SQL this SQLite track has been teaching from the ground up.

The Pattern That Stays the Same Everywhere

Notice that every snippet above follows the same shape, regardless of language: open a connection to the .db file, write SQL with placeholders instead of concatenated values, and pass the real values separately so the driver binds them safely. That consistency is one of SQLite's biggest practical strengths — the SQL you've learned throughout this track transfers directly, no matter which language ends up calling it.

Next: You've now seen SQLite from the SQL side and the application-code side. Head to SQLite vs MySQL vs PostgreSQL to see exactly when SQLite is the right tool for a job — and when a client-server database is the better call.