Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Loading Data  ›  Capstone Project

From a SQL Database into pandas

sqlite3 14 minpandas can send a SQL query through a database connection and receive the result as a DataFrame, and the database should filter and summarise before data crosses over.

From a SQL Database into pandas

The bookshop's till does not really write CSV files: it stores every sale in a database, and the CSV is an export someone remembers to run. Going straight to the database means fresher data and no middle step. pandas can send a SQL query and receive the answer as a DataFrame.

The rule

Connect, send a query, get a DataFrame; let the database filter first.

Python ships with sqlite3, a small database stored in a single file. No server needed:

import sqlite3
import pandas as pd

conn = sqlite3.connect("shop.db")

delhi = pd.read_sql(
    "SELECT branch, genre, copies FROM sales WHERE branch = 'Delhi'",
    conn,
)
conn.close()

read_sql runs the query and builds a DataFrame from the result, using the SQL column names as column names. Writing works too: sales.to_sql("sales", conn, if_exists="replace", index=False) creates a table from a DataFrame.

When a value comes from a variable, do not glue it into the string. Pass it as a parameter so the database treats it purely as data:

pd.read_sql("SELECT * FROM sales WHERE branch = ?", conn, params=("Delhi",))

For other databases, such as PostgreSQL or MySQL, you connect through SQLAlchemy, which gives every database the same connection style:

from sqlalchemy import create_engine
engine = create_engine("postgresql://user:password@host/shop")
pd.read_sql("SELECT * FROM sales", engine)

DuckDB is a third option built for analysis. It can run SQL directly on DataFrames and files already on your machine:

import duckdb
duckdb.sql("SELECT branch, SUM(copies) FROM sales GROUP BY branch").df()

The shortcut

Ask "Can the database shrink it first?" Filtering and grouping in SQL means only the answer crosses to Python. Pulling a million rows to keep ten wastes time and memory.

Delhi's total copies, the efficient wayStep 1 of 4
  1. The slow way

    pd.read_sql("SELECT * FROM sales", conn) pulls every row, then pandas filters and sums.

The trap is building queries with f-strings, like f"... WHERE branch = '{city}'". A value containing a quote breaks the query, and hostile input can change what it does. That is SQL injection, and params prevents it.

Drills

Answer fast — trust the rule.

quick drill

What does pd.read_sql(query, conn) return?

quick drill

Which is the safe way to use a branch name stored in city?

quick drill

You need one total per branch from a 50-million-row table. What is the better plan?

quick drill

Where does a sqlite3 database live?

Remember

  • Connect, send a query, get a DataFrame; let the database filter first.
  • sqlite3 is built in; SQLAlchemy connects to server databases; DuckDB runs SQL on local data.
  • Pass values with params, never by pasting them into the string.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainLet the database do the work

You need total copies per branch for one city from a very large sales table. Explain how you would get it into pandas safely and efficiently, and why.