🚧 Under construction — VoTechWorks is being built. A free tech program — complimentary, as our commitment to get America working.
voTechWorksGrade 13 · a vocational technology learning center, by urbanicity
newSchoolWorks.com › VoTechWorks › Technology & Design › Data Science & Analytics › SQL and PostgreSQL for Data Analytics › Lesson 8
TEC-DATA85-04 · Lesson 8 · 14 clock hours · lab

Connecting PostgreSQL to Python and BI Tools

Objective. Students connect a PostgreSQL database to Python using psycopg2 and SQLAlchemy, and to Power BI using the PostgreSQL connector, retrieving live query results for analysis and visualization.

⚠ Pending professional review

This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.

VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.

Why Connect PostgreSQL to External Tools?

Storing data in PostgreSQL is only the first step. Real analysis happens when you pull that data into Python for statistical work or into a visualization tool like Power BI for dashboards. This lesson covers two Python connection methods—psycopg2 and SQLAlchemy—and one BI connection method. Each approach serves a different workflow, but all three must handle credentials and queries securely.

SQL Injection: The Risk You Must Prevent

Before writing a single line of connection code, understand SQL injection. SQL injection occurs when untrusted user input is concatenated directly into a query string, allowing an attacker to alter the query's logic. For example, building a query with Python f-strings or string concatenation like `f"SELECT * FROM orders WHERE id = {user_input}"` is dangerous. If `user_input` is `1 OR 1=1`, the query returns every row in the table. In a destructive case, it could drop tables or expose passwords.

The defense is parameterized queries: you write a query template with placeholders, then pass values separately so the database driver handles escaping. The OWASP SQL Injection Prevention Cheat Sheet documents this as the primary defense. Never skip this step when your query touches any external input, including values from files, web forms, or command-line arguments.

Connecting with psycopg2

psycopg2 is the most widely used PostgreSQL adapter for Python. Install it with `pip install psycopg2-binary`. A basic connection looks like this:

```python

import psycopg2

import pandas as pd

conn = psycopg2.connect(

host="your_host",

dbname="your_db",

user="your_user",

password="your_password",

port=5432

)

cur = conn.cursor()

cur.execute(

"SELECT product_id, revenue FROM sales WHERE region = %s;",

("West",) # values passed as a tuple, NOT concatenated

)

rows = cur.fetchall()

df = pd.DataFrame(rows, columns=["product_id", "revenue"])

print(df.head())

cur.close()

conn.close()

```

The `%s` placeholder is psycopg2's parameterization syntax. The driver escapes the value before it reaches the database engine, preventing injection. Always close the cursor and connection when finished to release server resources. Never hard-code credentials in a script you will share or commit to version control; use environment variables or a config file excluded from your repository.

Connecting with SQLAlchemy Core

SQLAlchemy is a broader library that works with many database backends. Its Core layer (as opposed to the ORM layer) lets you reflect an existing table—meaning SQLAlchemy reads the table's structure directly from the database—and then run queries using Python objects rather than raw SQL strings.

Install with `pip install sqlalchemy psycopg2-binary`. A Core reflection example:

```python

from sqlalchemy import create_engine, MetaData, Table, select

engine = create_engine(

"postgresql+psycopg2://user:password@host:5432/dbname"

)

meta = MetaData()

meta.reflect(bind=engine)

sales = meta.tables["sales"]

with engine.connect() as con:

stmt = select(sales).where(sales.c.region == "West")

result = con.execute(stmt)

df = pd.DataFrame(result.fetchall(), columns=result.keys())

print(df.head())

```

SQLAlchemy parameterizes values automatically when you use its query-building methods. The connection string embeds credentials; the same caution about secrets management applies. SQLAlchemy is preferred when your project needs to support multiple databases or when you want Python-object-level query construction. psycopg2 direct connections are simpler and faster for PostgreSQL-only projects.

Connecting PostgreSQL to Power BI Desktop

Power BI Desktop is a free Windows application from Microsoft. To connect to PostgreSQL you need the Npgsql driver installed on your machine (Power BI's PostgreSQL connector depends on it; download from the Npgsql releases page and install before opening Power BI).

Steps in Power BI Desktop:

1. Open Power BI Desktop and click Get Data on the Home ribbon.

2. Search for PostgreSQL and select it, then click Connect.

3. Enter the server address and database name. Choose Import mode for this exercise (Import loads a snapshot; DirectQuery sends live queries on each refresh—both are valid but Import is simpler for class work).

4. Enter your credentials in the authentication dialog.

5. In the Navigator pane, select the two tables for this exercise and click Load.

6. Switch to Model view and drag a key field from one table to the matching field in the other to define a relationship.

7. Switch to Report view, add a bar chart visual from one table and a table visual from the other, then configure their fields.

8. Save the file as a .pbix file and submit it.

Power BI enforces the relationship you defined, so measures calculated across tables will join correctly. If visuals show blank data, check that the relationship is active (solid line in Model view) and that the key data types match on both sides.

Credentials and Security Reminders

Key terms8

psycopg2The most widely used Python adapter library for PostgreSQL, allowing Python scripts to open connections, execute SQL, and retrieve results.
Parameterized queryA query written with placeholders (such as %s in psycopg2) where values are passed separately so the database driver escapes them, preventing SQL injection.
SQL injectionAn attack in which malicious input is inserted into a query string to alter its logic, potentially exposing or destroying data. Prevented by parameterized queries.
SQLAlchemy CoreThe lower-level layer of the SQLAlchemy library that provides Python-object-based query construction and table reflection without requiring a full ORM mapping.
Table reflectionA SQLAlchemy feature that reads an existing table's column names and types directly from the database, so you do not have to redefine the structure in Python.
PostgreSQL connector (Power BI)The built-in Get Data option in Power BI Desktop that uses the Npgsql driver to connect to a PostgreSQL server and import or query its tables.
Import modeA Power BI data loading method that copies a snapshot of the data into the .pbix file, as opposed to DirectQuery which sends live queries to the source database.
Connection stringA formatted text value that encodes the driver, host, port, database name, and credentials needed to open a database connection, used by SQLAlchemy and other libraries.
In class: Python integration: students write a Python script that opens a psycopg2 connection, executes a parameterized query (using %s placeholders to prevent SQL injection), loads the result into a pandas DataFrame, and prints a five-row summary; instructor reviews the parameterization before the script is run. · SQLAlchemy ORM mini-exercise: students use SQLAlchemy Core to reflect an existing table and run the same query used in the psycopg2 exercise, then compare the two connection approaches in a written paragraph. · Power BI connection: students use the Get Data > PostgreSQL connector in Power BI Desktop to connect to the class database, import two tables, define a relationship in the model view, and build a two-visual report page; the report is saved and submitted as a .pbix file.
Materials: Python 3, psycopg2, SQLAlchemy, pandas (all via pip), Power BI Desktop (free), class PostgreSQL server credentials, SQL injection prevention reference (OWASP cheat sheet)
Check: Instructor runs the Python script and confirms parameterized query executes without error and returns the correct row count; .pbix file is opened and both visuals must display correct data from live database queries; both components must pass for the lesson to be marked complete.

Practice check8

Answer each question, then check it. Nothing is recorded; this is your own practice.

Data security and data governance
1. A student writes the following Python line to build a query: `query = f"SELECT * FROM users WHERE name = '{user_input}'"`. What is the primary security risk?
Data collection and storage
2. In psycopg2, which placeholder syntax is used for parameterized queries?
Data collection and storage
3. A student runs `meta.reflect(bind=engine)` in SQLAlchemy. What does this accomplish?
Data visualization and reporting
4. After loading two PostgreSQL tables into Power BI Desktop, a student's bar chart shows blank values. The most likely cause is:
Data visualization and reporting
5. Which of the following best describes the difference between Import mode and DirectQuery mode in Power BI?
Data security and data governance
6. To protect database credentials in a Python project, a best practice is to:
Data collection and storage
7. A student wants to run the same SQL query against PostgreSQL from both psycopg2 and SQLAlchemy Core, then compare the approaches. Which statement accurately describes a key difference?
Data security and data governance
8. Which resource does the lesson recommend as an authoritative reference for SQL injection prevention techniques?
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.