top of page

Welcome
to NumpyNinja Blogs

NumpyNinja: Blogs. Demystifying Tech,

One Blog at a Time.
Millions of views. 

Connect Python to PostgreSQL

May 2, 2025
5 min read

Python has lot of libraries one of them is SQLAlchemy. It is a Python SQL toolkit and Object Relational Mapper (ORM) that helps you work with relational databases like PostgreSQL, MySQL, SQLite, etc. We can  write queries using Python, instead of raw SQL


Two Main Layers of SQLAlchemy:

  1. Core (low-level)

    • Gives you direct SQL expression language and schema management.

    • Great for writing raw or dynamic SQL in Python.

  2. ORM (high-level)

    • Maps database tables to Python classes and handles relationships.

    • Useful when working with structured, object-oriented code.

 

Installation

There are two ways to install this python tool.

1.       Execute the below command in the Jupiter NoteBook terminal

!pip install sqlalchemy

 

2.       In the case of anaconda distribution of Python then you can install it from the conda terminal:

conda install -c anaconda sqlalchemy

 SQLAlchemy Core


Establish Connection with Database

The first step in establishing a connection with the PostgreSQL database is creating an engine object using the create_engine() function of SQLAlchemy. This method takes in the connection URL and returns a SQLAlchemy engine that references both a Dialect and a Pool.

engine = create_engine(dialect+driver://username:password@host:port/database_name)


Replace user, password, host, port, and database with your actual PostgreSQL credentials. If the database is running on the default port (5432), the :port part can be omitted. The postgresql+psycopg2 part specifies the database dialect and driver.


Example:

engine = create_engine("postgresql+psycopg2://postgres:Data%40123@localhost:5433/postgres")

dialect = postgresql

driver = psycopg2

username  = postgres(PostgreSQL username)

password= Data@12/3(PostgreSQL password)

Port = 5433( Server runs on different port not on the default port 5432)

Database name = postgres


This engine object acts as a central source of connections to a particular database, providing both a factory as well as a holding space called a connection pool for these database connections.

 The engine is typically a global object created just once for a particular database server


Escaping Special Characters such as @ signs in Passwords

When constructing the URL for create_engine(), the  special characters  in username and password should be URL encoded to be parsed correctly.


Below is the example URL

url = “postgresql+psycopg2://postgres:Data@12/3@localhost:5433/postgres"


1)The password given is ‘Data@12/3 ‘  here the “@” sign and ‘/’ characters should be encoded as %40 and %2F, respectively:

Now the URL is:

url = "postgresql+psycopg2://postgres:Data%40123@localhost:5433/postgres"


2) One more alternative way to escape special character is create the URL as object , don’t create the url as string . We can see how to do that.

The URL object is created using the URL.create() constructor method, passing all fields individually. Special characters such as those within passwords may be passed without any modification:

Example Code :

from sqlalchemy import URL 

url_object = URL.create(

     "postgresql+ psycopg2",

    username=" postgres ",

    password="Data@12/3",  # plain (unescaped) text

    host="localhost”

     port = 5433

    database="postgres",

)


Pass this URL object in create_engine() function :

from sqlalchemy import create_engine

engine = create_engine(url_object)


3)The best way to encode the special character is to use Python's urllib.parse.quote_plus function:

Example of Urllib

from urllib.parse import quote_plus

from sqlalchemy import create_engine

password = 'Data@12/3'

encoded_password = quote_plus(password)

engine = create_engine(f"postgresql+psycopg2:// postgres: {encoded_password}@localhost:5433/ postgres ")


Database API(DBAPI):

The Actual drivers that talk to the database.

The PostgreSQL dialect uses psycopg2 as the default DBAPI. Other PostgreSQL DBAPIs include pg8000 and asyncpg:

Example code:

·       engine = create_engine(f"postgresql+psycopg2:// postgres: {encoded_password}@localhost:5433/ postgres ")

 

·       engine = create_engine(f"postgresql+ asyncpg:// postgres: {encoded_password}@localhost:5433/ postgres ")

 

·       engine = create_engine(f"postgresql+ pg8000:// postgres: {encoded_password}@localhost:5433/ postgres ")

 

Getting a Connection

The methods engine.connect() opens a DBAPI connection. And Pandas read_sql() method is more flexible — it accepts raw SQL strings directly and handles them internally.

Example code

with engine.connect() as conn:

    dfResult = pd.read_sql(query, conn)

print(dfResult)


Dataset Used :

Treadmill Maximal Exercise Tests from the Exercise Physiology and Human Performance Lab of the University of Malaga.


Sample Code :

I did an analysis on Maximal Exercise Tests from the Exercise Physiology and Human Performance Lab of the University of Malaga.


Connected  to database using PostgreSQL and loaded the csv data in to the PostgreSQL and queried  the details of participants in test 1 and age > 50

         

import psycopg2 # it is a driver for postgres

import pandas as pd

from sqlalchemy import create_engine

 

df1=pd.read_csv('subject-info.csv')

df2=pd.read_csv('test_measure.csv')

merged_df=pd.merge(df1, df2, on=['ID','ID_test'],how='outer')           

# Connect to PostgreSQL

engine = reate_engine("postgresql+psycopg2://postgres:

# Upload to database

df2.to_sql("test_measure", engine, if_exists="replace", index=False)

df1.to_sql('subject_inform',engine,if_exists='replace',index=False)

merged_df.to_sql('subject_test',engine,if_exists='replace',index=False)

query = """SELECT * FROM subject_test

WHERE "ID_test" LIKE '%%1' AND "Age" > 50;"""

with engine.connect() as conn:

                        dfResult = pd.read_sql(query, conn)                                    

print(dfResult)

 

SQLAlchemy ORM:


"Object Relational Mapping (ORM) lets you interact with databases using Python classes instead of raw SQL."

This structure is known as a Declarative Mapping, defines at once both a Python object model, as well as database metadata that describes real SQL tables that exist in a particular database.

·       The mapping starts with a base class  and is created by calling upon the declarative_base() function, which produces a new base class.

 

·       Create the Individual mapped classes by making subclasses of Base. A mapped class typically refers to a single particular database table. The name of the table should be declared as  tablename class-level attribute.

 

·       Next, columns that are part of the table are declared, this database column, should be declared  such as Integer and String

 

·       All ORM mapped classes require at least one column be declared as part of the primary key, typically by using the Column.primary_key .

 

Installation :

pip install sqlalchemy psycopg2


Import and Base Setup:

from sqlalchemy import create_engine, Column, Integer, String

from sqlalchemy.orm import declarative_base, sessionmaker


Create Base Clase, Table and Columns:

            Base = declarative_base()

class User(Base):    tablename = 'users'

id = Column(Integer, primary_key=True)

            name = Column(String)

            email = Column(String)


Connecting to a Database :


Create_engine() function will create the engine object , Base.metadata collects table and schema definitions, Base.metadata.create_all() method tells SQLAlchemy to create all tables in the database that are defined by the ORM classes.

engine = create_engine("postgresql+psycopg2://postgres:Data%40123@

Base.metadata.create_all(engine)  # Creates the table

 

Creating a Session :

Session = sessionmaker(bind=engine)

session = Session()

sessionmaker() function that configures sessions  and  bind=engine, tells SQLAlchemy which database engine the sessions should connect to.

 

Query Execution:
·       Create Operation:

Creating new user in the database  with name is Alice and the email id is alice@example.com.

new_user = User(name="Alice", email="alice@example.com")

session.add(new_user)

session.commit()

users = session.query(User).all()

·       Read Operation:

Read the user from the database whose name is ‘Alice’

user = session.query(User).filter_by(name="Alice").first()

session.commit()

·       Update Operation:

Find the record with name Alice and update the email id of the particular record

user = session.query(User).filter_by(name="Alice").first()

session.commit()

·       Delete Operation

session.delete(user)

session.commit()


Dataset Used :

Treadmill Maximal Exercise Tests from the Exercise Physiology and Human Performance Lab of the University of Malaga.


Sample Code(ORM) :

Connected  to database using PostgreSQL and retrieved the details of participants in test 1 and age > 50

# Step 1: ORM base setup

Base = declarative_base()

 

# Step 2: Define ORM class for subject_test table

class SubjectTest(Base):    tablename = 'subject_test'   

            ID = Column(Integer, primary_key=True)

            ID_test = Column(String, primary_key=True)

             Age = Column(Integer)

            Temperature = Column(Float)

            Humidity = Column(Float)

            # Add more fields based on your actual table structure


# Step 3: Database connection

engine = create_engine("postgresql+psycopg2://postgres:Data%40123@localhost:5433/postgres")

Session = sessionmaker(bind=engine)

session = Session()

 

# Step 4: ORM-style query (equivalent to WHERE "ID_test" LIKE '%1' AND Age > 50)

results = session.query(SubjectTest).filter(SubjectTest.ID_test.like('%1'), SubjectTest.Age > 50).all()


# Step 5: Display results

for row in results:

print(f"ID: {row.ID}, ID_test: {row.ID_test}, Age: {row.Age}, Temp: {row.Temperature}, Humidity: {row.Humidity}")

session.close()


 

 

 

 

 
 

+1 (302) 200-8320

NumPy_Ninja_Logo (1).png

Numpy Ninja Inc. 8 The Grn Ste A Dover, DE 19901

© Copyright 2025 by Numpy Ninja Inc.

  • Twitter
  • LinkedIn
bottom of page