How to set up SQLAlchemy in your Python projects

Updated: January 3, 2024 By: Guest Contributor Post a comment

Overview

SQLAlchemy is an indispensable library for Python developers who interact with databases. This powerful ORM allows for easy database manipulation using Pythonic constructs. The setup process is straightforward and allows for scalable database application development.

Getting Started with SQLAlchemy

To begin, ensure you have the latest version of SQLAlchemy installed. If you haven’t yet, you can install it using pip:

pip install SQLAlchemy

This will install SQLAlchemy for your current Python environment. Once installed, you can begin by importing the required classes:

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship

Creating a Database Connection

Create an engine that manages connections to the database:

engine = create_engine('sqlite:///mydatabase.db')

The URL provided to create_engine is a connection string. In this case, we’re using SQLite, but SQLAlchemy supports many different databases.

Defining Models

Next, define your models by creating classes that inherit from Base:

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    fullname = Column(String)
    nickname = Column(String)

    def __repr__(self):
        return "<User(name='{}', fullname='{}', nickname='{}')>".format(
                self.name, self.fullname, self.nickname
            )

Once your models are defined, create the tables in the database:

Base.metadata.create_all(engine)

Creating a Session

To interact with the database, you must create and use a session:

Session = sessionmaker(bind=engine)
session = Session()

This session will serve as a staging zone for all the objects loaded into the database session. It’s also where you’ll query the database.

CRUD Operations

With the session, you can start adding and querying records:

new_user = User(name='john', fullname='John Doe', nickname='johnny')
session.add(new_user)
session.commit()

# Querying
user = session.query(User).filter_by(name='john').first()
print(user)

Working with Relationships

To add a sense of relations between tables, use the relationship function:

class Address(Base):
    __tablename__ = 'addresses'
    id = Column(Integer, primary_key=True)
    email_address = Column(String, nullable=False)
    user_id = Column(Integer, ForeignKey('users.id'))

    user = relationship("User", back_populates="addresses")

User.addresses = relationship("Address", order_by=Address.id, back_populates="user")

This creates a two-way relationship between Users and Addresses.

Advanced Usage

As projects grow in complexity, you may need more nuanced control over your sessions and transactions. You can use context managers or explicit transaction handling to provide a more fine-grained approach.

with session.begin() as transaction:
    try:
        session.add(new_user)
        transaction.commit()
    except Exception:
        transaction.rollback()
        raise

This is a safer method for handling transactions, ensuring that sessions are properly closed and resources are not leaked.

Migrations with Alembic

For continued development and production management of databases, integrate Alembic for handling migrations. Alembic tracks changes to your model schema and allows you to propagate changes to your production databases without loss of data:

pip install alembic
alembic init migrations

Conclusion

SQLAlchemy simplifies database interactions and brings ORM functionality to your Python projects. With the proper setup as detailed in this guide, you’ll be able to create scalable, maintainable, and efficient database applications.