python-backend
/

Python & SQL – Interacting with Relational Databases

Last Sync: Today

On this page

5
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

python-backend

Python & SQL – Interacting with Relational Databases

Python and the SQL Standard

Python interacts with relational databases through a standard specification called DB-API 2.0 (PEP 249). This ensures that whether you are using SQLite, MySQL, or PostgreSQL, the basic methods like connect(), execute(), and fetchone() remain consistent across different database drivers.

  1. Working with SQLite (Built-in)

Python comes with the sqlite3 module out of the box. It is perfect for local storage, mobile app testing, or small-scale automation tools. Since it's a file-based database, no server installation is required.

PythonRead-only
1
import sqlite3

# 1. Connect to a database file (creates it if it doesn't exist)
conn = sqlite3.connect('local_storage.db')
cursor = conn.cursor()

# 2. Create a table
cursor.execute('''CREATE TABLE IF NOT EXISTS projects 
               (id INTEGER PRIMARY KEY, name TEXT, stars INTEGER)''')

# 3. Insert data safely
project_data = ('Revochamp', 500)
cursor.execute("INSERT INTO projects (name, stars) VALUES (?, ?)", project_data)

# 4. Commit and close
conn.commit()
conn.close()

The Database Connection Workflow

Every SQL interaction in Python follows a specific hierarchy of objects: the Connection manages the link to the database, while the Cursor acts as a pointer to execute commands and fetch results.

  1. Parameterized Queries vs. Injection

As a Technical Lead, security is a priority. SQL Injection occurs when user input is directly concatenated into a query string. Python drivers prevent this by using placeholders (? for SQLite, %s for others).

PythonRead-only
1
user_id = "1 OR 1=1" # A common injection attack

# ❌ DANGEROUS
# cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")

# ✅ SAFE
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))

Common DB-API Methods

MethodPurposeReturns
execute()Runs a single SQL commandCursor object
executemany()Runs a command against a list of dataNone
fetchone()Retrieves the next row of a query resultTuple or None
fetchall()Retrieves all remaining rowsList of Tuples
commit()Saves all current changes to the DBNone
rollback()Undoes changes since the last commitNone

Try it yourself

import sqlite3

# Create an in-memory database for testing
conn = sqlite3.connect(':memory:')
cur = conn.cursor()

cur.execute("CREATE TABLE dev(name, lang)")
cur.execute("INSERT INTO dev VALUES (?, ?)", ("Kishore", "Python"))

# Query data
cur.execute("SELECT * FROM dev")
row = cur.fetchone()

print(f"Developer: {row[0]}, Language: {row[1]}")

Test Your Knowledge

Q1
of 3

Which object is responsible for executing SQL commands and fetching results?

A
Connection
B
Cursor
C
Driver
D
ORM
Q2
of 3

Which placeholder does SQLite use for parameterized queries?

A
%s
B
:val
C
?
D
$1
Q3
of 3

What command must be called to ensure data changes are saved to the database?

A
save()
B
push()
C
commit()
D
close()

Frequently Asked Questions

When should I use SQLite vs. a server-based SQL like PostgreSQL?

Use SQLite for local apps, prototypes, or read-heavy apps with low concurrency. Use PostgreSQL or MySQL for web applications with many simultaneous users and high write volumes.

What is 'conn.commit()' and why do I need it?

SQL databases use transactions. When you Insert or Update data, the changes are 'pending' in a temporary state. Calling commit() makes those changes permanent in the database file.

Can I return results as a Dictionary instead of a Tuple?

Yes. In SQLite, you can set 'conn.row_factory = sqlite3.Row'. This allows you to access columns by name (e.g., row['name']) instead of index (e.g., row[0]).

Previous

python database intro

Next

python orm

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.