Skip to content

Psycopg2 Module in Python: A Comprehensive Guide

Psycopg2 is a popular PostgreSQL adapter for Python. It is both efficient and feature-rich, making it the de facto standard for PostgreSQL access in Python. This guide will cover the key features, functionalities, and provide detailed examples to help you get started with Psycopg2.

Introduction to Psycopg2

Psycopg2 is designed to be a lightweight and efficient adapter for connecting to PostgreSQL databases from Python applications. It is highly compliant with the Python DB-API 2.0 specification and provides a robust set of features for working with PostgreSQL.

Key features of Psycopg2: - Fully compliant with the Python DB-API 2.0 specification - Efficient handling of large datasets - Support for PostgreSQL-specific data types and operations - Connection pooling and asynchronous support - Support for server-side cursors and COPY operations

Installation

To install Psycopg2, you can use pip:

pip install psycopg2

For binary installation:

pip install psycopg2-binary

Connecting to PostgreSQL

To connect to a PostgreSQL database, you need the database connection parameters such as host, database name, user, and password.

import psycopg2

# Connect to the PostgreSQL database
conn = psycopg2.connect(
    host="localhost",
    database="example_db",
    user="example_user",
    password="password"
)

# Create a cursor object
cur = conn.cursor()

# Close the cursor and connection
cur.close()
conn.close()

Basic CRUD Operations

Create

To insert data into a table:

# Open a cursor to perform database operations
cur = conn.cursor()

# Execute a command: this creates a new table
cur.execute('''
    CREATE TABLE users (
        id SERIAL PRIMARY KEY,
        name VARCHAR(100),
        age INTEGER
    )
''')

# Insert data into the table
cur.execute('''
    INSERT INTO users (name, age) VALUES (%s, %s)
''', ("Alice", 25))

# Commit the transaction
conn.commit()

# Close the cursor
cur.close()

Read

To retrieve data from a table:

# Open a cursor to perform database operations
cur = conn.cursor()

# Execute a command: retrieve all rows from the table
cur.execute('SELECT * FROM users')

# Fetch all rows from the executed query
rows = cur.fetchall()

# Print the rows
for row in rows:
    print(row)

# Close the cursor
cur.close()

Update

To update existing data:

# Open a cursor to perform database operations
cur = conn.cursor()

# Update data in the table
cur.execute('''
    UPDATE users SET age = %s WHERE name = %s
''', (26, "Alice"))

# Commit the transaction
conn.commit()

# Close the cursor
cur.close()

Delete

To delete data from a table:

# Open a cursor to perform database operations
cur = conn.cursor()

# Delete data from the table
cur.execute('''
    DELETE FROM users WHERE name = %s
''', ("Alice",))

# Commit the transaction
conn.commit()

# Close the cursor
cur.close()

Executing Transactions

Psycopg2 supports transactions, allowing you to commit or rollback changes as needed.

try:
    # Start a new transaction
    cur = conn.cursor()

    # Execute commands
    cur.execute("INSERT INTO users (name, age) VALUES (%s, %s)", ("Bob", 30))
    cur.execute("INSERT INTO users (name, age) VALUES (%s, %s)", ("Charlie", 35))

    # Commit the transaction
    conn.commit()
except Exception as e:
    # Rollback the transaction on error
    conn.rollback()
    print("Transaction failed:", e)
finally:
    cur.close()

Using Cursors

Cursors are used to interact with the database, allowing you to execute SQL commands and fetch results.

# Create a new cursor
cur = conn.cursor()

# Execute a command
cur.execute("SELECT * FROM users")

# Fetch a single row
row = cur.fetchone()
print(row)

# Fetch multiple rows
rows = cur.fetchmany(2)
for row in rows:
    print(row)

# Fetch all rows
rows = cur.fetchall()
for row in rows:
    print(row)

# Close the cursor
cur.close()

Connection Pooling

Connection pooling improves performance by reusing existing database connections.

from psycopg2 import pool

# Create a connection pool
connection_pool = pool.SimpleConnectionPool(
    1, 20,
    host="localhost",
    database="example_db",
    user="example_user",
    password="password"
)

# Get a connection from the pool
conn = connection_pool.getconn()

# Use the connection
cur = conn.cursor()
cur.execute("SELECT * FROM users")
rows = cur.fetchall()
for row in rows:
    print(row)
cur.close()

# Return the connection to the pool
connection_pool.putconn(conn)

# Close all connections in the pool
connection_pool.closeall()

Handling Binary Data

Psycopg2 supports working with binary data such as images and files.

from psycopg2 import Binary

# Open a cursor to perform database operations
cur = conn.cursor()

# Read binary data from a file
with open("image.png", "rb") as f:
    binary_data = f.read()

# Insert binary data into the table
cur.execute('''
    INSERT INTO files (filename, data) VALUES (%s, %s)
''', ("image.png", Binary(binary_data)))

# Commit the transaction
conn.commit()

# Retrieve binary data from the table
cur.execute('''
    SELECT data FROM files WHERE filename = %s
''', ("image.png",))
binary_data = cur.fetchone()[0]

# Write binary data to a file
with open("output_image.png", "wb") as f:
    f.write(binary_data)

# Close the cursor
cur.close()

Error Handling

Psycopg2 provides comprehensive error handling for database operations.

import psycopg2

try:
    # Execute a command that will fail
    cur.execute("INSERT INTO users (name, age) VALUES (%s, %s)", ("Alice", "twenty-five"))
except psycopg2.DatabaseError as e:
    print("Database error:", e)
except psycopg2.IntegrityError as e:
    print("Integrity error:", e)
finally:
    cur.close()
    conn.close()

Advanced Features

Copy Command

The COPY command is used for efficient bulk data transfer.

# Open a cursor to perform database operations
cur = conn.cursor()

# Copy data from a file to a table
with open("data.csv", "r") as f:
    cur.copy_from(f, "users", sep=",")

# Commit the transaction
conn.commit()

# Close the cursor
cur.close()

Asynchronous Support

Psycopg2 supports asynchronous operations for improved performance.

import psycopg2.extras

# Create an asynchronous connection
conn = psycopg2.connect(dsn, async_=1)

# Use a cursor for asynchronous operations
cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
cur.execute("SELECT * FROM users")
conn.poll()

while conn.notifies:
    notify = conn.notifies.pop()
    print("Received notification:", notify.payload)

# Close the cursor and connection
cur.close()
conn.close()

Large Objects

Psycopg2 supports handling large objects (LOBs) such as large text or binary files.

# Open a cursor to perform database operations
cur = conn.cursor()

# Create a new large object
oid = cur.lo_creat()

# Open the large object for writing
lo = cur.lo_open(oid, psycopg2.LARGE_OBJECT_WRITE)

# Write data to the large object
lo.write("This is a large object")

# Close the large object
lo.close()

# Commit the transaction
conn.commit()

# Open the large object for reading
lo = cur.lo_open(oid, psycopg2.LARGE_OBJECT_READ)

# Read data from the large object
data = lo.read()

# Close the large object
lo.close()

# Close the cursor
cur.close()

Conclusion

Psycopg2 is a powerful and efficient adapter for PostgreSQL, providing comprehensive tools for database access and management in Python. Its support for advanced features such as connection pooling, asynchronous operations, and large objects makes it suitable for a wide range of applications. By mastering the core features and functionalities of Psycopg2, you can efficiently manage PostgreSQL databases and perform complex operations with ease. This guide should serve as a solid foundation for building database-driven applications using Psycopg2.