[파이썬] SQLAlchemy 다대다 관계 설정

In database management systems, a many-to-many relationship occurs when multiple records from one table are associated with multiple records from another table. This type of relationship is common in various scenarios, such as tagging systems, social networks, and e-commerce platforms.

When working with Python and SQLAlchemy, a powerful and popular Object-Relational Mapping (ORM) library, you can easily establish and manage many-to-many relationships between database tables.

Setting up the Many-to-Many Relationship

To define a many-to-many relationship in SQLAlchemy, you need three tables: the primary table, the related table, and an intermediary table. The intermediary table is responsible for connecting the two primary tables and holding their foreign keys.

Here’s an example scenario: you have two tables, Books and Authors, and they have a many-to-many relationship. Each book can have multiple authors, and each author can be associated with multiple books.

from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

book_author = Table('book_author', Base.metadata,
    Column('book_id', Integer, ForeignKey('books.id')),
    Column('author_id', Integer, ForeignKey('authors.id'))
)

class Book(Base):
    __tablename__ = 'books'
    
    id = Column(Integer, primary_key=True)
    title = Column(String)
    authors = relationship('Author', secondary=book_author, back_populates='books')

class Author(Base):
    __tablename__ = 'authors'
    
    id = Column(Integer, primary_key=True)
    name = Column(String)
    books = relationship('Book', secondary=book_author, back_populates='authors')

In the above code, we define the books and authors tables using the SQLAlchemy’s declarative syntax. We then create the book_author intermediary table using the Table class.

The Book and Author classes define their respective columns and establish a many-to-many relationship through the books and authors attributes. The secondary argument specifies the intermediary table, while the back_populates argument allows bidirectional navigation between the two primary tables.

Using the Many-to-Many Relationship

Once the many-to-many relationship is set up, you can easily add, retrieve, update, and delete records in the associated tables.

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine('your_database_connection_string')
Session = sessionmaker(bind=engine)
session = Session()

# Creating books and authors
book1 = Book(title='Book 1')
book2 = Book(title='Book 2')

author1 = Author(name='Author 1')
author2 = Author(name='Author 2')

# Associating authors with books
book1.authors.append(author1)
book1.authors.append(author2)
book2.authors.append(author2)

# Adding records to the session and committing
session.add_all([book1, book2, author1, author2])
session.commit()

# Retrieving authors of a book
book = session.query(Book).filter_by(title='Book 1').first()
authors = book.authors

# Retrieving books of an author
author = session.query(Author).filter_by(name='Author 2').first()
books = author.books

# Removing an author from a book
book.authors.remove(author2)
session.commit()

In the above code, a session is created and used to manage the database operations. We create instances of Book and Author and associate them using the authors attribute. After adding the records to the session and committing, we can query the associated records using bidirectional navigation.

Conclusion

SQLAlchemy provides an intuitive way to configure and manage many-to-many relationships in Python. By using the intermediary table pattern, you can establish connections between tables and easily perform operations on the associated records. This flexibility and convenience make SQLAlchemy a powerful choice for working with complex database relationships in your Python projects.